awk - ブロックから開始単語と終了単語を含む行を削除します。

awk - ブロックから開始単語と終了単語を含む行を削除します。

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

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ますp0
  • 次に、true(つまりゼロ以外)のprint場合にのみ行を入力します。p
  • 最後に、で始まり、現在印刷中でない行が表示されている場合Done(つまり、pなど)、印刷を再開するように0設定します。p

ここで最も大きな違いは、印刷のみが行われることです。後ろに印刷を続行するかどうかを決定しましたが、次の行で印刷を再開するかどうかを確認する前に決定しませんでした。

おすすめ記事