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

6yt4nkrj  于 2022-11-15  发布在  Perl
关注(0)|答案(6)|浏览(211)

我有一个简单的用例,我有一个文件,比如

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不是下一行,我不知道它发生了多少行,任何使用sedawk或任何bash相关的解决方案都将工作,任何帮助都将不胜感激。

kiayqfof

kiayqfof1#

使用awk

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

ekqde3dh2#

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

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

这只会将结果行打印到屏幕上。如果你想改变文件(“就地”),添加-i开关(perl -i -wpe'...'),或者更好的-i.bak来保留备份。

ffvjumwh

ffvjumwh3#

使用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
pepwfjgg

pepwfjgg4#

这是(由当前接受的答案)提出的:

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/'

请参阅Specifying file to process to Perl one-liner

nvbavucw

nvbavucw5#

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.*?)aaa\n/$1YES REPLACE THIS\n/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_3和非贪婪地搜索aaa\n之前的任何字符,并将其全部替换为我在aaa\n之前匹配的字符,表示为(),后面跟着YES REPLACE THIS\n

  • (在perl 5.30.0中测试)*
fdx2calv

fdx2calv6#

ed适用于自动编辑文件:

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

找到与line_3匹配的第一行,然后c更改与aaa匹配的第一行之后的第一行,最后w将修改后的文件重新写入。

相关问题