不會去到sed
的基礎知識,這裏是你的sed
命令細分:
$!N
:如果沒有文件結尾,下一行追加到模式空間。這兩行將被換行符分開(\n
)。在這個時候你的模式空間是201408\n201409
。
/^\(.*\)\n\1$/!P
:如果將模式空間不包含一個換行(\n
)分隔開的兩個類似的內容,然後P
RINT直到第一換行符(\n
)。所以這將打印201408
到STDOUT。在第二次迭代期間,模式空間將有201409\n201409
,並且因爲它失敗正則表達式,沒有打印,我們繼續下一個命令。
D
:D
直到第一個換行符(\n
)並重復sed
腳本。重複週期中記住你的模式空間仍具有201409
所以在第一次迭代201408
期間被打印,但201409
沒有得到打印,直到到達文件的結尾這是當你的正則表達式將再次成爲真實,內容將被打印。
如果你繼承了很多的sed
代碼,我會強烈建議sedsed工具,它是寫在python
,將幫助您瞭解錯綜複雜和晦澀sed
,往往可以成爲一個維護的噩夢。 (我沒有顯示所有的迭代,因爲它很詳細,但你得到的圖片。我已經添加了幾個意見,什麼輸出真正的意思。還注意到我使用單一引號,因爲我在Mac(BSD Unix等),而不是Windows)中:
$ sedsed.py -d '$!N; /^\(.*\)\n\1$/!P; D' file
PATT:201408$ # This shows your current pattern space
HOLD:$ # This shows your current hold buffer
COMM:$ !N # This shows the command that is going to run
PATT:201408$ # This shows the pattern space after the command has ran
201409$
HOLD:$ # This shows the hold buffer after the command has ran
COMM:/^\(.*\)\n\1$/ !P # This shows the command being ran
201408 # Anything without a <TAG:> is what gets printed to STDOUT
PATT:201408$
201409$
HOLD:$
COMM:D
PATT:201409$
HOLD:$
...
...
...
COMM:$ !N
PATT:201409$
HOLD:$
COMM:/^\(.*\)\n\1$/ !P
201409
PATT:201409$
HOLD:$
COMM:D
我也建議,一旦你得到了你的sed
命令被用於,將它們移植到一個更友好的腳本語言編寫的想法如awk
,perl
或python
A你確定那是它的樣子嗎?我在問,因爲shell會用雙引號替換變量,'$!'擴展爲最近執行的後臺進程的PID,這很可能導致'sed'看到一些意外的輸入...( '$ /'不會被擴展,因爲它不是一個有效的變量)。 – twalberg 2014-09-05 20:59:32
@twalberg是的,我只是再次檢查,這正是它在代碼中的顯示方式,它的工作原理。我的電腦很奇怪,但對於任何sed命令,它都不會使用單引號(就像大多數地方所說的那樣),但大部分時間都不帶引號。對於這一行,只有在使用雙引號時纔有效。 – user2755209 2014-09-05 21:12:24
@ user2755209在我的'ubuntu'上運行你的命令,我得到這個錯誤'-bash:!P:event not found'。你在什麼操作系統上。 – Jotne 2014-09-05 21:14:20