入力ファイルから一部のレコードを削除しようとしています。
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
- ターゲットラインが表示されるまで、一致しないラインを印刷し続けます。
- ターゲット行が満たされたら、ファイルが使い果たされるまですべての行を印刷し続けます。