如何使用Perl跨多行搜索和替换?

时间:2021-09-09 16:48:26
$ perl --version
This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi

$ echo -e "foo\nbar" > baz.txt
$ perl -p -e 's/foo\nbar/FOO\nBAR/m' baz.txt
foo
bar

How can I get this replacement to work?

我怎样才能让这个替换工作?

2 个解决方案

#1


38  

You can use the -0 switch to change the input separator:

您可以使用-0开关更改输入分隔符:

perl -0777pe 's/foo\nbar/FOO\nBAR/' baz.txt

-0777 sets the separator to undef, -0 alone sets it to \0 which might work for text files not containing the null byte.

-0777将分隔符设置为undef,-0将其设置为\ 0,这可能适用于不包含空字节的文本文件。

Note that /m is needless as the regex does not contain ^ nor $.

注意/ m是不必要的,因为正则表达式不包含^也不是$。

#2


5  

It has to do with the -p switch. It reads input one line at a time. So you cannot run a regexp against a newline between two lines because it will never match. One thing you can do is to read all input modifying variable $/ and apply the regexp to it. One way:

它与-p开关有关。它一次读取一行输入。所以你不能对两行之间的换行运行正则表达式,因为它永远不会匹配。您可以做的一件事是读取所有输入修改变量$ /并将正则表达式应用于它。单程:

perl -e 'undef $/; $s = <>; $s =~ s/foo\nbar/FOO\nBAR/; print $s' baz.txt

It yields:

它产生:

FOO
BAR

#1


38  

You can use the -0 switch to change the input separator:

您可以使用-0开关更改输入分隔符:

perl -0777pe 's/foo\nbar/FOO\nBAR/' baz.txt

-0777 sets the separator to undef, -0 alone sets it to \0 which might work for text files not containing the null byte.

-0777将分隔符设置为undef,-0将其设置为\ 0,这可能适用于不包含空字节的文本文件。

Note that /m is needless as the regex does not contain ^ nor $.

注意/ m是不必要的,因为正则表达式不包含^也不是$。

#2


5  

It has to do with the -p switch. It reads input one line at a time. So you cannot run a regexp against a newline between two lines because it will never match. One thing you can do is to read all input modifying variable $/ and apply the regexp to it. One way:

它与-p开关有关。它一次读取一行输入。所以你不能对两行之间的换行运行正则表达式,因为它永远不会匹配。您可以做的一件事是读取所有输入修改变量$ /并将正则表达式应用于它。单程:

perl -e 'undef $/; $s = <>; $s =~ s/foo\nbar/FOO\nBAR/; print $s' baz.txt

It yields:

它产生:

FOO
BAR