sedを使用して特定のレコードを削除したい

sedを使用して特定のレコードを削除したい

入力ファイルから一部のレコードを削除しようとしています。

list.txt
tag1,slate1,flag1,status0,8,1
tag2,slate2,flag2,status0,2,3
tag1,slate1,flag1,status1,8,1
tag2,slate2,flag2,status1,2,3
tag1,slate1,flag1,status0,0,1
tag2,slate2,flag2,status1,2,3
tag1,slate1,flag1,status1,1,2
tag2,slate2,flag2,status1,1,2
tag1,slate1,flag1,status1,3,4

期待される出力: list.txt

tag2,slate2,flag2,status0,2,3
tag2,slate2,flag2,status1,2,3
tag1,slate1,flag1,status0,0,1 -> deleted records above this and matching [tag1,slate1,flag1]
tag2,slate2,flag2,status1,2,3
tag1,slate1,flag1,status1,1,2
tag2,slate2,flag2,status1,1,2
tag1,slate1,flag1,status1,3,4

コードを試してみてください。

sed '/tag2,slate2,flag2,status0/d' list1.txt

ただし、これにより、tag1、slate1、flag1、status0、0、1、tag1、slate1、flag1、status1、1、2などのレコードが削除されます。

レコードが「tag1、slate1、flag1、status0、0、1」に達したときにsedを停止する方法はありますか?

そして、"tag1,slate1,flag1,status0"が見つからない場合、"tag1,slate1,flag1"に一致するレコードを削除する必要はありません。

出力を得るための提案。

答え1

あなたはそれを使用することができますawk

awk '
NR == FNR && /tag1,slate1,flag1,status0/{last_matching=FNR}
NR != FNR && FNR<last_matching && /tag1,slate1,flag1/{next}
NR != FNR
' list.txt list.txt

awkファイルを2回読みます。

  • 初めて実行するとき(NR == FNR)...
    • 最後の一致FNR(=ファイルのレコード/行番号)を変数に保存します。
  • 2回目の実行で(NR != FNR)...
    • 一致するすべての行をスキップします(--> /tag1,slate1,flag1/{next})。
    • しかし、last_matching(--> FNR<last_matching)のみ可能です。
    • を使用して、残りのすべての行を印刷しますNR != FNR

答え2

使用sedストリームエディタユーティリティを使用すると、次のことができます。

sed -ne ':top
/^tag1,slate1,flag1,status0,0,1$/!{
  /^tag1,slate1,flag1,/!p;n
  btop
}
:n;p;n;bn
' list.txt
  • ターゲットラインが表示されるまで、一致しないラインを印刷し続けます。
  • ターゲット行が満たされたら、ファイルが使い果たされるまですべての行を印刷し続けます。

関連情報