2011-01-27 6 views
3

私は

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

がファイルFOOの最後の2行をプリントアウトすることを知っているが、私はなぜ理解していません。

私はマニュアルページを読んで、Nが現在処理されている行などの次の行に参加していることを知っていますが、ここで何が起こっているのかを誰かが「良い英語」で説明できるでしょうか?

ありがとうございました!

+1

配管 'cat foo'は'第2のプロセス Benoit

+0

が合意しましたが、私は旧式のdemoggification引数を開始しようとしていませんでした - むしろ単なる例でした。実際の使用では、複数のファイルと処理の前に$!Nを使用して列などを追加しています。私の検索では、上記の参照が見つかりました。上記の例は説明が良いものだと思っていますが、明快だと思います。 – wibble

+0

@Benoit:あなたのnit-pickingを選択する;)リダイレクションはしばしば不要です: '2nd-process foo'。 –

答えて

4

は、そのスクリプトが(アウレリオJargasによって)sedsedデバッガを介して実行時に次のようになります。

$ 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です。

+0

'sedsed'を共有してくれてありがとう、それは非常に便利なツールのようです! –

1

$!N;$!Dは二つの文、$!N$!Dからなるsedプログラムです。

$!Nは(!によって否定$)入力の最後のファイルの最後の行以外のすべてを一致し、(あなたが言ったように、自分が現在精査の下の行に入力の次の行を追加しており、それにNのコマンドを実行します"パターンスペース")。換言すれば、sedはパターン・スペース内に2つの行を持ち、次の行に進んでいます。

$!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 
+0

... "と入力し、パターンスペースを最初の改行まで拭きます。Dは、次の行を読むときにsedがパターンスペース全体をワイピングするのを防ぎます。あなたは、それが4つの行を含むファイルを処理する例を、ステップバイステップで与えることができると思いますか? – wibble

+0

@wibble: 'sed'は通常、次の行を読むときにパターンスペースを上書きします。 'D'はこれを防ぎます。あなたはどのような例を探していますか? –