如何在bash中替换特定行后替换文件中的行

  • 本文关键字:替换 文件 bash bash perl awk sed
  • 更新时间 :
  • 英文 :


我有一个简单的用例,我有一个像

这样的文件
line_1
anything
anything
anything
aaa
line_2
line_3
anything
anything
anything
aaa
anything
anything
line_4
aaa

现在我必须替换line_3之后的第一个aaa

输出——

line_1
anything
anything
anything
aaa
line_2
line_3
anything
anything
anything
YES REPLACE THIS
anything
anything
line_4
aaa

我可以用-

替换下一行的任何内容
sed -i '/line_3/{n; s/aaa/YES REPLACE THIS/}' file.txt

但是aaa不是下一行,我不知道它发生多少行之后,任何使用sed,awk或任何bash相关的解决方案都将工作,任何帮助将不胜感激。

使用awk

awk '/line_3/{f=1} f&&/aaa/{$0="YES REPLACE THIS";f=0} 1' file

一旦它看到line_3设置一个标志,一旦它找到并替换模式就取消它

perl -wpe'if ($on) { $on = 0 if s/aaa/XXX/ }; $on = 1 if /^line_3$/' file

这只将结果行打印到屏幕上。如果您想要更改文件("in-place")添加-i开关(perl -i -wpe'...'),或者更好的-i.bak也保留备份。

使用sed

$ sed '/line_3/,/line_4/{0,/^aaa/s/^aaa/YES REPLACE THIS/}' input_file
line_1
anything
anything
anything
aaa
line_2
line_3
anything
anything
anything
YES REPLACE THIS
anything
anything
line_4
aaa

这是建议的(由当前接受的答案):

perl -pe'$f = 1 if /^line_3$/; if ($f) { $f = 0 if s/^aaa$/YES REPLACE THIS/ };'

简化为:

perl -pe'$f ||= /^line_3$/; $f &&= !s/^aaa$/YES REPLACE THIS/;'

但是触发器运算符为我们做了很多工作!

perl -pe'/^line_3$/ .. s/^aaa$/YES REPLACE THIS/'

参见指定文件处理到Perl一行程序。

仅在perl中使用替换,让file.txt的内容为

line_1
anything
anything
anything
aaa
line_2
line_3
anything
anything
anything
aaa
anything
anything
line_4
aaa

然后

perl -p -0777 -e 's/(line_3.*?)aaan/$1YES REPLACE THISn/s' file.txt

给输出

line_1
anything
anything
anything
aaa
line_2
line_3
anything
anything
anything
YES REPLACE THIS
anything
anything
line_4
aaa

说明:-p-e表示像sed一样工作,-0777表示将整个文件挤成一行。s/-替换,/s-使.也匹配换行字符,我匹配line_3aaan之前的非贪婪的任何字符,并替换所有我在aaan之前匹配的由()表示的YES REPLACE THISn

ed适合自动化ed下载文件:

ed -s file.txt <<<EOF
/line_3/;/aaa/,.c
YES REPLACE THIS
.
w
EOF

找到第一行匹配line_3,然后c更改匹配aaa之后的第一行,最后是w将修改后的文件返回。

最新更新