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

Gab*_*ley 17 regex perl multiline

$ 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
Run Code Online (Sandbox Code Playgroud)

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

cho*_*oba 38

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

perl -0777pe 's/foo\nbar/FOO\nBAR/' baz.txt
Run Code Online (Sandbox Code Playgroud)

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

请注意,/m由于正则表达式不包含^也不是必需的$.

  • `-0`和`-0777`之间的另一个区别是,对于一个空的`baz.txt`,前者获得0条记录,后者获得1条空记录(这里对于`s/foo没有区别) \nbar/FOO \nBAR /`但是例如用于`s/^/prefix /`). (3认同)
  • @Сухой27,没有.如果文件不包含NUL字符,`-0`只会覆盖文件.文本文件通常不包含这些字符.因此对于文本文件来说,它通常没有什么区别,但是如果你想要将文件放入其中,无论它包含什么,那么你想要的是"-0777".`-0`更多用于处理`find -print0`或`grep -lZ`(NUL分隔记录)的输出.比较`printf'和\ 0b\0'| perl -l -0 -ne'print $.'```printf'a\0b\0'| perl -l -0777 -ne'print $.'` (2认同)

Bir*_*rei 5

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

perl -e 'undef $/; $s = <>; $s =~ s/foo\nbar/FOO\nBAR/; print $s' baz.txt
Run Code Online (Sandbox Code Playgroud)

它产生:

FOO
BAR
Run Code Online (Sandbox Code Playgroud)