固定テキストから始まり、最初の空白行までのGrep


9

次のprova.txtようなファイルがあります。

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

extra1
extra2
bla

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

extra2
bla
bla

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

「ここから始めましょう」から最初の空白行にグレップアウトする必要があります。出力は次のようになります。

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

「ここから始めます」の後の行はランダムであるため、-A -B grepフラグは機能しません。

cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt

空白行が表示されるまで、最初の行を取得する方法を見つけるのを手伝ってくれますか(「ここから開始」など)。「ここからつかむ」の後にランダムなラインがいくつあるか予測できません。

UNIXと互換性のある解決策はありがたいです(grep、sed、awkはperlや同様のものより優れています)。

編集:@ john1024による素晴らしい応答の後、私はそれが可能かどうか知りたいです:

1°ブロックをソートします(ここから開始するように開始:1、1、2)。

2°4つの(アルファベット順でランダムな)行を削除しますfix1、fix2、fix3、fix4が常に4です

3°は、sort -uコマンドのように、ランダムな複製を最終的に削除します

最終的な出力は次のようになります。

# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4

#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

または

# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

2番目の出力は、最初の出力よりも優れています。他のUNIXコマンドマジックが必要です。


1
これは、java jstack出力から特定のスレッドのスタックトレースを取得するのに非常に役立ちます。このQ&Aを見つけてよかった!
BenjaminBallard

回答:


13

awkの使用

試してください:

$ awk '/Start to grab/,/^$/' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

/Start to grab/,/^$/範囲を定義します。一致するすべての行でStart to grab始まり、その後の最初の空行で終わり^$ます。

sedの使用

非常に似たロジックで:

$ sed -n '/Start to grab/,/^$/p' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

-n明示的に要求しない限り、何も出力しないようにsedに指示します。 /Start to grab/,/^$/pで定義された範囲の行を印刷するように指示します/Start to grab/,/^$/


あなたの解決策は完璧です、私は何かを追加するために私の質問を編集しました。レリーはあなたの助けに感謝します。ありがとう
heisen

1

一部の人々のユースケースに役立つ可能性があるため、私は代替ソリューションを投稿しています。このソリューションは指定された要件に正確に準拠していません。最適なソリューションについては、@ John1024からの回答を参照してください。

Record Separatorを空の文字列に設定してawkを使用できます。awkはこれらを空白の改行として解釈します。

$ awk '/Start/' RS= prova.txt 
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

このバージョンでは、出力の空白の改行は保持されません。存在する場合は、試合前のコンテキストも表示されます。この動作は、ファイル内の何かをgrepしていて、その一部である改行区切りのブロックを表示したい場合に非常に役立ちます。次に例を示します。

$ awk '/random1546/' RS= prova.txt 
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

たとえば、これはiniファイル内のものをgrepするときに便利です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.