2017-12-27 284 views
0

我试着去理解下面的Perl命令“删除所有连续的空行,只留下一个”:删除所有连续的空行,只留下一个过程:perl -00 -pe'

perl -00 -pe '' 

Perl One-Liners Explained

首先它没有任何代码,-e是空的。接下来它有一个愚蠢的-00命令行选项 。此命令行选项打开 段落slurp模式。段落是两条换行符之间的文本。所有 其他换行符都会被忽略。该段落放入“$ _”中, “-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

任何声称*“接下来它有一个愚蠢的-00命令行选项”*的源都不会被信任。 – Borodin

+0

第二个'0'是'-e'的参数,即要运行的程序。 – ikegami

回答

6

最好在有疑问时阅读官方文档。见-0perlrun$/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记得我们是否在“分隔符”中,只有当我们第一次输入这样一个空格时打印换行符。

+0

这是非常好的,只是你没有正确解释'-l'做了什么以及它如何影响'perl -lpe's/^ \ s + $ //'' – Borodin

+0

'$ in_sep =! print'很可怕 – Borodin

+0

'--'是什么意思?我想让这个脚本改变原始文件,而不仅仅是将输出推送到控制台,所以我尝试'perl -lpe's/^ \ s + $ //' - file | perl -i-00pe0'然而输出仍然到控制台,为什么?也许是因为在管道的最后部分输入文件是标准输出,那么我如何才能将更改推送到原始文件? – rapt

1

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' 
+0

编写答案时请不要压缩您的代码。虽然您可能想要对自己造成难以辨认的代码,但对* Stack Overflow做出回答是不恰当的。 – Borodin

+0

@Borodin,感谢您的反馈,短代码的原因是单行,我同意一些空间,它更容易理解。 –

+0

@NahuelFouilleul第一个你建议的实际上更容易理解,一旦我找出了正则表达式:)如果该块在中间切成一个白色段落,第二个是否会工作?我能否获得至少2条换行符? – rapt

相关问题