2017-12-27 282 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

相關問題