指定された文字列を含む2行間をgrepする

指定された文字列を含む2行間をgrepする

私はこのシンプルなプラットファイル(file.txt)を持っています

a43
test1
abc
cvb
bnm
test2
test1
def
ijk
xyz
test2
kfo

test1とtest2の間のすべての行を2つの形式で必要とします。最初の形式では、次のような2つの新しいファイルを作成します。

新しいファイル1.txt:

test1
abc
cvb
bnm
test2

新しいファイル2.txt

test1
def
ijk
xyz
test2

2 番目の形式では、次のように 1 つの新しいファイルのみが作成されます。

新しいファイル.txt

test1abccvbbnmtest2
test1abccvbbnmtest2

何か提案はありますか?

2番目のフォームではこれを使用しました

sed -n '/test1/,/test2/p' file.txt > newfile.txt

しかし、次のような結果が出ました

test1abccvbbnmtest2test1abccvbbnmtest2

次のような戻り行が必要です:

test1abccvbbnmtest2
test1abccvbbnmtest2

答え1

最初のケースの awk ワンライナー:

awk '/^test1/{file++; on=1} on{print >("newfile" file ".txt")} /^test2/{on=0}' file.txt

それはこう言います:

  • 見つかった場合はtest1、ファイル番号を増分して出力を開始します(つまり、turn on)。
  • オンにすると、ファイル名「newfileFILE.txt」に行が印刷されます。ここで、FILE はファイル番号です。
  • test2見つかった場合は出力を終了(つまりオフにする)

newfile.txt次に、シェル ワンライナーを使用して2 つのファイルを変換できます。

for file in newfile?.txt; do tr -d '\n' <$file; echo; done > newfile.txt

これは、各ファイルごとにすべての改行を削除することを意味します。

答え2

2番目のフォームの場合:

sed -n '/test1/,/test2/p' file.txt | xargs > newfile.txt ; sed 's/test2/&\n/g' newfile.txt | sed -e 's/^[ \t]*//'
  • sed -n '/test1/,/test2/p' file.txt --> test1 と test2 の間のテキストをキャプチャします
  • xargs > newfile.txt --> 実質的にはテキストを「行」に変換しますが、xargs の目的はおそらく異なります。
  • sed 's/test2/&\n/g' newfile.txt --> "test2" パターンの後に改行を追加します
  • sed -e 's/^[ \t]*//' --> 各行の先頭のスペースを削除します。

関連情報