2014-09-05 139 views
0

我在下面有一行SED,這是我每個月運行的批處理命令。它是由我之前的人寫的,我期待了解這些代碼的各個部分。從這兩個輸出中我可以看出,當順序行重複時,它會佔用一行並刪除另一行,我只是不明白它是如何完成這一行的。SED代碼解釋

sed "$!N; /^\(.*\)\n\1$/!P; D" finalish.txt > final.txt 

Exmple的 - Finalish.txt

201408 
201409 
201409 
201409 
201409 

- Final.txt

201408 
201409 
+0

A你確定那是它的樣子嗎?我在問,因爲shell會用雙引號替換變量,'$!'擴展爲最近執行的後臺進程的PID,這很可能導致'sed'看到一些意外的輸入...( '$ /'不會被擴展,因爲它不是一個有效的變量)。 – twalberg 2014-09-05 20:59:32

+0

@twalberg是的,我只是再次檢查,這正是它在代碼中的顯示方式,它的工作原理。我的電腦很奇怪,但對於任何sed命令,它都不會使用單引號(就像大多數地方所說的那樣),但大部分時間都不帶引號。對於這一行,只有在使用雙引號時纔有效。 – user2755209 2014-09-05 21:12:24

+0

@ user2755209在我的'ubuntu'上運行你的命令,我得到這個錯誤'-bash:!P:event not found'。你在什麼操作系統上。 – Jotne 2014-09-05 21:14:20

回答

2

不會去到sed的基礎知識,這裏是你的sed命令細分:

  • $!N:如果沒有文件結尾,下一行追加到模式空間。這兩行將被換行符分開(\n)。在這個時候你的模式空間是201408\n201409
  • /^\(.*\)\n\1$/!P:如果將模式空間包含一個換行(\n)分隔開的兩個類似的內容,然後P RINT直到第一換行符(\n)。所以這將打印201408到STDOUT。在第二次迭代期間,模式空間將有201409\n201409,並且因爲它失敗正則表達式,沒有打印,我們繼續下一個命令。
  • DD直到第一個換行符(\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,perlpython

0

這不會幫助你理解sed,但這裏是一個awk,僅僅得到獨特的線條。

awk '!seen[$0]++' finalish.txt 
201408 
201409 
+0

這將挑選出不相鄰的等效線路,這似乎並不是預期的效果...... – twalberg 2014-09-05 21:13:33

+0

@twalberg然後有些人會這樣做:awk NR> 1 && $ 0!= a {print a} {a = $ 0} END {print}'file' – Jotne 2014-09-05 21:18:37