1

私は(sedのウェブサイトhttp://sed.sourceforge.net/sed1line.txtから)このワンライナーを持っています:

sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'

その目的は、AAA、BBB、またはCCCのいずれかを段落で検索することです。

スクリプトについての私の理解:

  • '/./'は、空ではないすべての行に一致します
  • '{}'括弧内のすべてのコマンドは、一致した行を処理します
  • 「H」は、一致した行でホールドスペースを追加します
  • '$!d'は、パターンスペースから最後の行以外のすべてを削除します
  • 'x'はパターンスペースとホールドスペースを交換します
  • '/ AAA /!d' AAA段落を検索し、印刷します

私には明らかではないこと:

  1. ホールドスペースには(段落ごとに)いくつかの別々の行が必要ですが、なぜ段落全体を検索できるのですか?ホールドスペースの行は1行にマージされていますか?
  2. そして、sedは、ホールドスペースで1つの段落が終了し、もう1つの段落がいつ開始するかをどのように知るのでしょうか。
  3. なぜ「$!d」を追加する必要があるのですか、なぜ「$ d」では不十分なのですか?この場合、「-n」を省略して「$!d」の代わりに「$ p」を使用できないのはなぜですか?

コメントありがとうございます!

私のテストデータ(すべての段落にXXが含まれているものと一致します):

YYaaaa
aaa1
aaa2
aXX3
aaa4

YYbbbb
bbb1
bbb2

YYcccc
ccc1
ccc2
ccc3
cXX4
ccc5

YYdddd
ddd1
dXX2

次のコマンドが使用されます。

sed -ne '/./{H;$!d};x;/XX/p' test2

バージョン:

$ sed --version
GNU sed-Version 4.2.1
$ bash --version
GNU bash, Version 4.2.10(1)-release (x86_64-pc-linux-gnu)
4

1 に答える 1

1

段落を個別の行として保留スペース(H)に収集し、空の行にヒットすると/./失敗し、x基本的に次の段落の保留スペースをザッピングします。

最後の段落を正しく処理するには、空行が続かない段落に対処する必要があるため、最後の行から空行が続くかのようにフォールスルーします。これは、特定のパターンで何かを収集するスクリプトの一般的なイディオムです(言い換えると、そのようなスクリプトがファイルの最後で最後に収集されたデータを処理できないのは一般的なエラーです)。

つまり、空でない行を表示している場合は、それを保留スペースに追加し、ファイルの最後の行でない限り、それを削除して、スクリプトの最初から次の入力行でやり直します。(おそらくあなたの理解はd完全ではありませんでしたか?これはどういう$!d意味ですか。)

Otherwise, we have an empty line, or end of file, and the hold space contains zero or more lines of text (one paragraph, possibly empty). Exchange them into the pattern space (the current, empty, line conveniently moves to the hold space) and examine the pattern space. If it fails to match one of our expressions, delete it. Otherwise, the default action is to print the entire pattern space.

于 2012-04-04T19:45:15.300 に答える