2011-01-27 100 views
3

我知道

cat foo | sed '$!N;$!D' 

將打印出來的文件FOO的最後兩行,但我不明白爲什麼。

我已經閱讀手冊頁,並知道N加入到當前處理的行的下一行等 - 但有人可以解釋'好英語'與操作順序相匹配的一步一步嗎?

謝謝!

+1

將`cat foo`管道連接到某個進程效率低於執行第二個進程 Benoit 2011-01-27 13:57:44

+0

表示同意,但我並沒有試圖開始陳舊的舊的demoggification說法 - 而只是一個例子。在實際使用中,我在使用$!N添加列之前將多個文件和處理合並在一起。在我的搜索中,我找到了上述的參考資料。我認爲上面給出的例子是一個很好的例子,並且仍然有效我認爲清晰。 – wibble 2011-01-27 14:11:00

+0

@Benoit:挑選你的挑剔;)重定向通常是不必要的:`第二流程foo`。 – 2011-01-27 17:26:19

回答

4

下面是該腳本看起來當通過sedsed調試運行像(由奧雷利奧Jargas):

$ echo -e 'a\nb\nc\nd' | sed '$!N;$!D'  PATT:^a$ 
PATT:^a$ 
COMM:$ !N 
PATT:^a\Nb$ 
COMM:$ !D 
PATT:^b$ 
COMM:$ !N 
PATT:^b\Nc$ 
COMM:$ !D 
PATT:^c$ 
COMM:$ !N 
PATT:^c\Nd$ 
COMM:$ !D 
PATT:^c\Nd$ 
c 
d 

我過濾因爲它沒有被使用,所以會顯示保持空間的行(「HOLD」)。 「PATT」顯示模式空間中的內容,「COMM」顯示即將執行的命令。 「\ N」表示嵌入的換行符。當然,「^」和「$」表示字符串的開始和結束。

!N附加下一行,!D刪除上一行並循環到腳本的開頭,而不進行隱式打印。讀取最後一行時,$!測試失敗,因此沒有任何可做的事情並且腳本退出並執行模式空間中剩餘內容的隱式打印(因爲-n未在參數中指定)。

免責聲明:我是sedsed項目的貢獻者,並做了一些小改進,包括擴展顏色支持,添加^行開始指示器和對Python 3的初步支持。最新版本(尚未最近觸及)是here

1

$!N;$!D是一個sed程序,由兩個語句$!N$!D組成。

$!N匹配的一切,但輸入($!否定)的最後一個文件的最後一行,並在其上運行N命令,就像你說的你自己輸入的下一行追加到行目前正在審查(在「模式空間」)。換句話說,sed現在在模式空間中有兩行,並且已經前進到下一行。

$!D也匹配除最後一行之外的所有內容,並將模式空間擦除爲第一個換行符。 D還可防止sed在讀取下一行時擦除整個圖案空間。

因此,正在執行的算法大致是:

For every line up to but not including the last { 
    Read the next line and append it to the pattern space 
    If still not at the last line 
     Delete the first line in the pattern space 
} 
Print the pattern space