以下のようなファイルがあります。
~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
の間にあるすべての行が取得されます。 どうすれば取得できますか? と を調べましたが、オプションが見つかりませんでした。PAR1
Par Finished
awk
sed
答え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.*?(?=Par 終了)" ip.txt これはPar1ライン1です これはPar1ライン2です
変数を次のように変更するPAR2
$ s="PAR2" $ grep -oPz "(?s)${s}.*?\n\K.*?(?=Par 終了)" ip.txt これはPar2ライン1です これはPar2ライン2です