一致する条件の間でファイルのテキストの一部を抽出する方法

一致する条件の間でファイルのテキストの一部を抽出する方法

以下のファイルがあります。

~PAR1~
This is Par1 line 1
This is Par1 line 2

Par Finished

~PAR2~
This is Par2 line 1
This is Par2 line 2

Par Finished

を通過すると、との間のすべての行を取得する必要がPAR1あります。どうやって入手できますか?調査中ですが、オプションが見つかりません。PAR1Par Finishedawksed

答え1

ヘッダーとフッター行が必要な場合は簡単ですsed

sed -n "/^~PAR1~$/,/Par Finished/p"

変数で使用するのは簡単です。

START=PAR1
sed -n "/^~$START~$/,/Par Finished/p"

最後の行を変数にすることもできます。

START=PAR1
END="Par Finished"
sed -n "/^~$START~$/,/$END/p"

結果は次のとおりです。

~PAR1~
This is Par1 line 1
This is Par1 line 2

Par Finished

これで、開始/終了行を必要とせず、空行も必要としないと、状況がより複雑になります。

おそらくより良い方法があります。しかし、これは私にとって効果的です。

sed -n "/^~$START~$/,/$END/ { /^~$START~$/d ; /$END/d ; /^$/d ; p }"

これの結果は

This is Par1 line 1
This is Par1 line 2

答え2

対応する行(オプションの末尾の空白行を含む)をレコード区切り文字として使用できますPar Finished(その後、それを置き換えてレコードを完了します)。

awk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {print $0,"\nPar Finished"}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2

Par Finished

awkがある場合は、GNU特殊変数を使用してレコード区切り文字を復元できますRT(必要に応じて追加の改行文字を削除することもできます)。

gawk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {sub("\n*$", "", RT); print $0,RT}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2

Par Finished

もちろん通過する必要がない場合変える Par1単純な正規表現範囲を使用します。

awk '/PAR1/,/Par Finished/' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2

Par Finished

答え3

十分に小さいファイルgrep入力の場合pcre

$ s="PAR1"

$ grep -oPz "(?s)[^\n]*${s}.*?\n.*?Par Finished.*?\n" ip.txt 
~PAR1~
This is Par1 line 1
This is Par1 line 2

Par Finished

パターン間の線を取得するには:

$ grep -oPz "(?s)${s}.*?\n\K.*?(?=波完了)" ip.txt
Par1 1号線です
Par1 2号線です

変数を次に変更します。PAR2

$s="PAR2"
$ grep -oPz "(?s)${s}.*?\n\K.*?(?=波完了)" ip.txt
Par2 1号線です
Par2 2号線です

引用: 複数行検索のための正規表現(grep)

関連情報