如何使用 Perl 搜索和替换多行?
Posted
技术标签:
【中文标题】如何使用 Perl 搜索和替换多行?【英文标题】:How do I search and replace across multiple lines with Perl? 【发布时间】:2013-05-20 12:01:30 【问题描述】:$ 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
我怎样才能让这个替代品起作用?
【问题讨论】:
尝试添加g
标志:'s/foo\nbar/FOO\nBAR/gm'
。
@Jerry no,g
选项用于全局行为,与我的问题无关。
正式注明@GabeKopley
【参考方案1】:
您可以使用-0
开关更改输入分隔符:
perl -0777pe 's/foo\nbar/FOO\nBAR/' baz.txt
-0777
将分隔符设置为undef
,-0
单独将其设置为\0
,这可能适用于不包含空字节的文本文件。
请注意,/m
是不必要的,因为正则表达式不包含 ^
或 $
。
【讨论】:
比我的好多了。我不习惯-0
开关,但在这种情况下非常适合。 +1 为此。
-0
将 $/
设置为 "\000"
并将 -0777
设置为 undef
,但两者都执行文件 slurp。 :o
@Сухой27,没有。 -0
仅在文件不包含 NUL 字符时才删除文件。文本文件通常不包含这些字符。因此,对于文本文件,它通常不会有什么不同,但如果你想把文件吞进去,不管它可能包含什么,那就是你想要的 -0777
。 -0
更多用于处理find -print0
或grep -lZ
(NUL 分隔记录)的输出。比较 printf 'a\0b\0' | perl -l -0 -ne 'print $.'
和 printf 'a\0b\0' | perl -l -0777 -ne 'print $.'
您可以将-0
/-z
/--null
与 GNU grep
或 GNU sed
一起使用,因为您没有其他选择。它们没有 slurp 模式,但您可以使用 -z
模拟它,只要您可以保证输入不包含 NUL 字符。 (你仍然可以使用pcregrep -M ...
或gsed ':1;$!N;b1...
)
-0
和 -0777
之间的另一个区别是,对于一个空的 baz.txt
,您将获得 0 条记录,前者为 1 条记录,后者为 1 条空记录(这里没有区别s/foo\nbar/FOO\nBAR/
但例如 s/^/prefix/
)。【参考方案2】:
它与-p
开关有关。它一次读取一行输入。因此,您不能对两行之间的换行符运行正则表达式,因为它永远不会匹配。您可以做的一件事是读取所有输入修改变量$/
并将正则表达式应用于它。一种方式:
perl -e 'undef $/; $s = <>; $s =~ s/foo\nbar/FOO\nBAR/; print $s' baz.txt
它产生:
FOO
BAR
【讨论】:
以上是关于如何使用 Perl 搜索和替换多行?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 sed 和 awk(和 perl)中搜索和替换任意文字字符串