編集済み: @john1024 による素晴らしい回答を受けて、次のことが可能かどうか知りたいです:

編集済み: @john1024 による素晴らしい回答を受けて、次のことが可能かどうか知りたいです:

次のようなファイルがあります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

そして、「ここから取得を開始」から最初の空白行まで grep する必要があります。出力は次のようになります。

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

ご覧のとおり、「Start to grab here」の後の行はランダムなので、-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

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/,/^$/

答え2

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

レコード セパレータを空の文字列に設定して 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 するときにこれが便利だと思います。

関連情報