web-dev-qa-db-ja.com

Sed 2つの文字列間のテキストを抽出する

Sedの使用を手伝ってください。以下のようなファイルがあります。

START=A
  xxxxx
  xxxxx
END
START=A
  xxxxx
  xxxxx
END
START=A
  xxxxx
  xxxxx
END
START=B
  xxxxx
  xxxxx
END
START=A
  xxxxx
  xxxxx
END
START=C
  xxxxx
  xxxxx
END
START=A
  xxxxx
  xxxxx
END
START=D
  xxxxx
  xxxxx
END

START = A、ENDの間のテキストを取得したい。以下のクエリを使用しました。

sed '/^START=A/, / ^END/!d' input_file

ここでの問題は、

START=A
  xxxxx
  xxxxx
END
START=D
  xxxxx
  xxxxx
END

の代わりに

START=A
  xxxxx
  xxxxx
END

セドは貪欲に見つけた。

これを解決するために私を助けてください。

前もって感謝します。

上記を達成するためにAWKを使用できますか?

8
ranganath111
sed -n '/^START=A$/,/^END$/p' data

-nオプションは、デフォルトでは印刷しないことを意味します。次に、スクリプトは「START=Aを含む行と次のENDの間で印刷を行う」と言います。

awkを使用して行うこともできます。

パターンは、コンマで区切られた2つのパターンで構成されます。この場合、アクションは、最初のパターンの発生から2番目のパターンの発生までのすべての行に対して実行されます。

(Mac OS Xのman awkから)。

awk '/^START=A$/,/^END$/ { print }' data

問題のデータファイルの変更された形式を考えると:

START=A
  xxx01
  xxx02
END
START=A
  xxx03
  xxx04
END
START=A
  xxx05
  xxx06
END
START=B
  xxx07
  xxx08
END
START=A
  xxx09
  xxx10
END
START=C
  xxx11
  xxx12
END
START=A
  xxx13
  xxx14
END
START=D
  xxx15
  xxx16
END

GNU sedまたはMac OS X(BSD)sedを使用した出力と、GNU awkまたはBSD awkを使用した出力は同じです。

START=A
  xxx01
  xxx02
END
START=A
  xxx03
  xxx04
END
START=A
  xxx05
  xxx06
END
START=A
  xxx09
  xxx10
END
START=A
  xxx13
  xxx14
END

印刷されたデータのさまざまなブロックがファイルのどこから来たのかを簡単に確認できるように、データファイルをどのように変更したかに注意してください。

別の出力要件がある場合(「START = AとENDの間の最初のブロックのみ」、「最後の...のみ」など)は、質問でそれを明確に示す必要があります。

24

基本バージョン...

sed -n '/START=A/,/END/p' yourfile

より堅牢なバージョン...

sed -n '/^ *START=A *$/,/^ *END *$/p' yourfile
3
xagyg

sed式の終了前にスペースがあります。つまり、/ ^END/。したがって、sedは開始パターンを取得しますが、終了パターンは取得せず、最後まで印刷を続けます。使用する sed '/^START=A/, /^END/!d' input_file(通知/^END/

2
abasu