web-dev-qa-db-ja.com

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

ファイルがあります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コマンドマジックが必要です。

9
heisen

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/,/^$/で定義された範囲の行を印刷するように指示します。

13
John1024

一部の人々のユースケースに役立つ可能性があるため、私は代替ソリューションを投稿しています。このソリューションは指定された要件に正確に準拠していません。最適なソリューションについては、@ 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

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

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

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

1
htaccess