Regex 找到匹配项后,Sed内联替换文本文件中的句子

Regex 找到匹配项后,Sed内联替换文本文件中的句子,regex,bash,sed,Regex,Bash,Sed,我试图在找到匹配项后替换文本文件中句子的第一个实例。请注意,”引号包含在搜索中 我正在搜索的第一个实例是:'database'=>'localhost' 我将第一个实例替换为:'database'=>'new\u database' 我只想在字符串'replace\u THIS' 我目前有前两个要点: sed -i file -e "1s/'database' => 'localhost'/'database' => 'new_database'/;t" -e "1,/'data

我试图在找到匹配项后替换文本文件中句子的第一个实例。请注意,
引号包含在搜索中

  • 我正在搜索的第一个实例是:
    'database'=>'localhost'
  • 我将第一个实例替换为:
    'database'=>'new\u database'
  • 我只想在字符串
    'replace\u THIS'
我目前有前两个要点:

sed -i file -e "1s/'database' => 'localhost'/'database' => 'new_database'/;t" -e "1,/'database' => 'localhost'/s//'database' => 'new_database'/" file
输入文件

'local config' ... 'data'
    'more data'
    'database' => 'localhost'
    'even more data'
'REPLACE_AFTER_THIS' ... 'data'
    'more data'
    'even more data'
    'database' => 'localhost'
'live config'
    'database' => 'localhost'
预期的输出文件(同一文件内联更改)

上面的示例演示了除了字符串
'database'=>'localhost'
,没有期望的数据格式,该字符串的第一次出现需要在
'REPLACE\u THIS'
之后更改

但是,我不知道如何在找到某个字符串后才执行上述操作。我已经尝试使用grep和一个模式来检索
REPLACE\u THIS
之后的所有文本,但是随后管道传输到sed而不是使用
-I
标志不再对文件执行任何更改


在文件中找到给定字符串后,如何更改当前正在使用的解决方案,以包含替换句子第一个实例的内容?

您可以使用awk:

temp=$(mktemp /tmp/temporary-file.XXXXXXXX)
awk "/REPLACE_AFTER_THIS/{u=1} u && 
 sub(/'database' => 'localhost'/, \"'database' => 'new_database'\") {u=0} 1" file > "$temp"
输出:

'local config' ... 'data'
    'more data'
    'database' => 'localhost'
    'even more data'
'REPLACE_AFTER_THIS' ... 'data'
    'more data'
    'even more data'
    'database' => 'new_database'
'live config'
    'database' => 'localhost'
使用GNU sed尝试以下操作:

sed -i "/'REPLACE_AFTER_THIS'/,/'database' => 'localhost'/s/'database' => 'localhost'/'database' => 'new_database'/" file

显示示例输入和该示例输入所需的输出。@Cyrus听起来很明显?添加了一个任意示例,尽管我确信要点中不需要。嗯,为什么
'local config'
在那里?请注意:除了字符串
'database'=>'localhost'
(或者这只是您的输出?)之外,没有预期的数据格式。它可能不存在。文件中唯一保证的数据是:
REPLACE\u THIS
'database'=>'localhost'
。啊,这就是我问的原因(或者这只是你的输出?),这更有意义,我会尝试一下:-)它不会更新文件。它按预期打印出更改,但需要使用更改更新文件。因此,我使用sed的内联
-I
。不幸的是,我有GNUAWK3.1.8。如果脚本不能访问目录,只能访问文件,并且我不想使用
setfacl
获得对目录的额外权限,以使其正常工作,那么必须创建一个文件然后覆盖它不是一件好事:-(
sed -i "/'REPLACE_AFTER_THIS'/,/'database' => 'localhost'/s/'database' => 'localhost'/'database' => 'new_database'/" file