如何使用 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 -print0grep -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)中搜索和替换任意文字字符串

Perl 命令行多行替换

如何使用 Perl 从文件中删除多行 C 注释?

perl在IC领域应用—复制多行通配符替换为数字

从另一个 Perl 脚本内部调用 Perl 搜索和替换命令时不起作用

Perl 语法 - 高级特性