我尝试理解以下Perl命令“删除所有连续的空行,只留下一个”:
perl -00 -pe ''
首先它没有任何代码,-e是空的。接下来它有一个愚蠢的-00命令行选项。此命令行选项打开段落啜食模式。段落是两个换行符之间的文本。所有其他新行都被忽略了。段落放在“$ _”中,“ - p”选项将其打印出来。
我不遵循这个解释。也许措辞不准确。
所以"A paragraph is text between two newlines."
但是每一行都是两个换行符之间的文本。
"All the other newlines get ignored."
但两个连续换行之间没有换行符。
"The paragraph gets put in "$_" and the "-p" option prints it out."
由于它是在每两个换行符之间的文本中进行的,因此将整个文件拼凑成一个长行。它看起来像这个命令应该怎么做?
它还说,另一种写它的方法是
perl -00pe0
最右边的0
代表什么?
无论如何,我实际想要实现的是删除所有连续的白线,只留下一个空行。白线我指的是一条可能不是空的行,但只有空白字符(和换行符)。是否可以修改上述命令以匹配此情况?
如有疑问,最好阅读官方文档。参见-0
中的perlrun和$/
中的perlvar。
该文应该说
段落是由两个或多个换行符分隔的文本。
“所有其他新行”然后成为不成对出现的新行。 “忽略”表示它们不分隔段落,但它们包含在从输入中读取的字符串中。
-e0
只执行0
作为代码。 0和1免于warnings,任何其他值也可以工作,但与-w
会警告你:
Useless use of a constant (2) in void context at -e line 1.
要实现所需,您可以分两步处理文件:首先,从仅空白行中删除任何空格
perl -lpe 's/^\s+$//'
(-l
不需要与所有空格一起删除换行符)。
然后运行已知的
perl -00pe0
所以,整个管道变成了
perl -lpe 's/^\s+$//' -- file | perl -00pe0
当然,您可以通过一次致电perl
完成所有工作:
perl -ne 'if (/\S/) { $in_sep = ! print }
elsif (! $in_sep) { $in_sep = print "\n" }' -- file
$ in_sep会记住我们是否“在分隔符中”,只有当我们第一次输入这样的空格块时才会打印换行符。
B::Deparse
模块可用于揭示单行程序背后的有效代码。它可以通过添加像这样的-MO=Deparse
在单行启用
perl -MO=Deparse -00 -p -e 0
-0
选项设置$/
的值:输入记录分隔符,并使用""
将其设置为空字符串-00
启用“段落模式”,这意味着输入将在一个或多个空行处分割
-0
的另一个特殊值是-0777
,它禁用记录分隔符以便读取整个文件。 $/
可以像\<number>
一样设置为\8192
,以便输入具有固定长度的记录,但这不能通过-0
选项获得
如果文件不是太长,请读取整个文件
perl -0777 -pe 's/\n\s+\n/\n\n/g'
否则,文件可以以8192字节的块的形式读取,但在某些情况下,必须在处理之前读取下一个块。
perl -pe 'BEGIN { $/ = \8192} $_ .= <> while /\n\s*$/ && ! eof; s/\n\s+\n/\n\n/g'