4

我经常使用正则表达式来转换文本。

要从命令行转换巨大的文本文件,perl 让我这样做:

perl -pe < in.txt > out.txt

但这本质上是逐行的。偶尔,我想匹配多行的东西。

如何在命令行中执行此操作?

4

2 回答 2

7

要 slurp 文件而不是逐行处理,请使用-0777开关:

perl -0777 -pe 's/.../.../g' in.txt > out.txt

如记录在perlrun #Command Switches

特殊值-00将导致 Perl 在段落模式下 slurp 文件。任何值-0400或更高的值都会导致 Perl 读取整个文件,但按照惯例,该值-0777是通常用于此目的的值。

显然,对于大文件,这可能无法正常工作,在这种情况下,您需要编写某种类型的缓冲区来进行替换。尽管没有有关您意图的真实信息,但我们无法提供更好的建议。

于 2014-06-13T00:46:10.597 回答
1

跨越线边界

所以你想跨越线边界...

你很可能已经pcregrep安装了。您可能知道,PCRE 代表Perl-Compatible Regular Expressions,并且该库绝对是 Perl 风格的,尽管与 Perl 不同。

多行匹配,需要开启多行模式-M,和(?m)

跑步pcregrep -M "(?s)^b.*\d+" text.txt

在这个文本文件上:

a
b
c11

输出将是

b
c11

而 grep 将返回空。

文档摘录:

-M, --multiline 允许模式匹配多于一行。当给出这个选项时,模式可能有用地包含文字换行符和内部出现的 ^ 和 $ 字符。成功匹配的输出可能包含多行,最后一行是匹配结束的那一行。如果匹配的字符串以换行序列结束,则输出在该行的末尾结束。

设置此选项时,PCRE 库以“多行”模式调用。可以匹配的行数是有限制的,这是由 pcregrep 在扫描输入文件时缓冲输入文件的方式所施加的。但是,pcregrep 确保至少 8K 字符或文档的其余部分(以较短者为准)可用于前向匹配,并且类似地,之前的 8K 字符(或之前的所有字符,如果少于 8K)可用于前向匹配。保证可用于后向断言。此选项在逐行读取输入时不起作用(请参阅 --line-buffered。)

于 2014-06-12T02:07:23.373 回答