以下のファイルがあります。
Line1
line2
Begin1
Select is running
Done1
Begin
Update is in progress
Done
Begin2
Select is running
Done2
Begin3
select is running
Done4
line last
更新という単語を見つけて、開始(前の行)から始めて、完了(次の行)までブロックを削除したいと思います。
したがって、最終出力は次のようになります。
Line1
Line2
Begin1
Select is running
Done1
Begin2
Select is running
Done2
Begin3
select is running
Done4
line last
削除するには、次のコードを使用しますが、残念ながらBeing文字列とDone文字列を持たない行をすべて削除します。
awk -i inplace '/BEGIN/ {f=1} f {s=s?s"\n"$0:$0;if ($0~/update/) f=s=0} /COMMIT/ && f {print s;f=s=0}' filename
Begin1
Select is running
Done1
Begin2
Select is running
Done2
Begin3
select is running
Done4
修正する:
別のユースケース:
他のファイルの構造が次のような場合
Line1
line2
Begin
Select is running
Done
Begin
Done
Update is in progress
Begin2
Select is running
Done2
Begin3
select is running
Done4
line last
ここBegin
に来るDone
前にupdate
。だから私はその3行を削除したいと思います。これを達成するために推奨される方法はありますか?
答え1
たとえば、このawkスクリプトを次のように保存します717212.awk
。
BEGIN { p=1 }
/^Update/ { p=0 }
p { print $0 }
p==0 && /^Done/ { p=1 }
これにより、与えられた入力ファイルに対する要求が行われますinputfile
。
awk -f 717212.awk inputfile
どのように機能するかは、必要なものを正確にリストすることです。特定の条件に従って印刷したいので、印刷するかどうかを追跡するBEGIN
変数をningに定義します。p
^
()で始まる行が表示されている場合は、印刷したくないことを意味しUpdate
ますp
。0
- 次に、true(つまりゼロ以外)の
print
場合にのみ行を入力します。p
- 最後に、で始まり、現在印刷中でない行が表示されている場合
Done
(つまり、p
など)、印刷を再開するように0
設定します。p
ここで最も大きな違いは、印刷のみが行われることです。後ろに印刷を続行するかどうかを決定しましたが、次の行で印刷を再開するかどうかを確認する前に決定しませんでした。