GREP / SEDまたはAWK:パターンマッチングに基づいてファイルの全体の段落を印刷します。 [重複]

GREP / SEDまたはAWK:パターンマッチングに基づいてファイルの全体の段落を印刷します。 [重複]

各段落が約15行の数百の段落を含むファイルがあります。パターンを探す必要があります。発生数:1。このパターンが段落で見つかった場合は、段落全体を印刷する必要があります。段落は2つの改行に分かれています。

私は明らかにファイルの最初の項目を印刷する次のコード行を試しました。何らかの方法でループを使用してこれらのイベントをすべて印刷することはできません。

sed -n '1,/Occurrence: 1/p' ystdef.txt | tail -9 > ystalarm.txt

gこれを行うには(グローバル)フラグを使用できますかsed?それではどうですか?

私はこのコマンドを知っていますが、grep -A/B/C私のCygwin端末では動作しません。

答え1

入力レコードが少なくとも2つの改行シーケンスで区切られるawkの「短絡モード」を使用できます。RS空の文字列に設定すると有効になります。

awk -v RS= '/Occurance: 1/' ystdef.txt

これらの段落はすべて一緒に折り畳まれて印刷されます(内容の間に改行文字を含む)。 awkを使用すると、出力区切り文字を入力区切り文字と一致させることはできませんが(一部のGNU awk拡張を除く)、段落区切り文字を2つの改行で簡単に正規化できます。

awk -v RS= -v ORS='\n\n' '/Occurance: 1/' ystdef.txt

最後に追加の改行をしたくない場合:

awk -v RS= '/Occurance: 1/ {if (not_first) print ""; print; not_first=1}' ystdef.txt

答え2

これはGNUにありますsed

sed '/./{H;$!d};x;/SEARCH/!d'

移植可能/POSIX構文:

sed -e '/./{H;$!d;}' -e 'x;/SEARCH/!d'

行に 1 つ以上の文字が含まれている場合は、前のスペースが追加されます。最後のH行で削除されます。これは、空でないすべての行が保存され、出力から削除されることを意味します。!$

だから、いいえ d削除すると、ホールドとパターンスペースの内容がsed変わります。xこれにより、1行の空行のみのスペースと、最後の空行以降のすべての行のパターンスペースが残ります。

sed次にパターンを解決します/SEARCH/!見つからない場合は印刷せずにdパターンスペースを削除し、それ以外の場合はデフォルトで段落を印刷します。

以下は、あなたの質問を入力として受け入れるシェル関数です。

注 - 読みやすくするために、このウェブサイトでコードが強調表示されると、処理されたデータにコメントが表示されます。ハッシュなしまたはそのまま動作します。

_pgraph() { 
    sed '/./{H;$!d};x;/'"$1"'/!d'
} <<\DATA
#    I have a file with hundreds of paragraphs of
#    around 15 lines each. I need to search for a
#    pattern, say Occurance: 1. If this pattern is
#    found in the para, I need to print the entire
#    paragraph. Note that the paragraps are seperared
#    by 2 new line characters.

#    I have tried the below line of code and this
#    obviously prints the first occurence in the
#    file. I am somehow unable to use a loop and
#    print all such occurances.

#    sed -n '1,/Occurance: 1/p' ystdef.txt | tail -9 >
#    ystalarm.txt Can I use the g (global) flag with
#    sed to make this work? If yes, how?

#    Note that I am aware of the grep -A/B/C commands
#    but they wont work on my cygwin terminal.
DATA

今できます:

_pgraph Note

###OUTPUT

#    I have a file with hundreds of paragraphs of
#    around 15 lines each. I need to search for a
#    pattern, say Occurance: 1. If this pattern is
#    found in the para, I need to print the entire
#    paragraph. Note that the paragraps are seperared
#    by 2 new line characters.

#    Note that I am aware of the grep -A/B/C commands
#    but they wont work on my cygwin terminal.

またはより具体的に:

_pgraph 'Note that I'

#    Note that I am aware of the grep -A/B/C commands
#    but they wont work on my cygwin terminal.

関数自体にテキスト入力を添付することなく、すべてのファイルに対して同じことを実行できます。関数定義のすべての項目を削除し、次のように実行します<<\DATADATA

_pgraph 'PATTERN' </path/to/input.file

答え3

Perlでは、「ショートモード」を使用できます。

perl -ne 'BEGIN{ $/ = "" } print if /pattern/' input

関連情報