awkとパイプ値を使用してパイプで区切られたファイルから重複エントリを削除するには?

awkとパイプ値を使用してパイプで区切られたファイルから重複エントリを削除するには?

この方法を使用して、パイプで区切られたファイルから複数の列に基づいて重複エントリを削除しようとしています。複数の動的列に基づいて重複を削除する方法 ところで、以下のように二重引用符内の値にパイプがあることを発見しました。

3|XX|""|2022-04-05T21:39:22.899Z|2022-04-05T21:37:59Z|X7
3|XX|"2025035|6|15|0|0|15|39"|2022-04-05T21:39:22.899Z|2022-04-05T21:37:59Z|X7

最後の列の位置 6 と位置 2 を確認すると、2 つの行が重複しますが、位置 3 のパイプのため動作しません。下のコードから二重引用符でパイプをエスケープするにはどうすればよいですか?

$4='2,6'
awk -v c="$4"  -F'|' 'BEGIN{split(c,k,",")} {key=""; for (i in k) key=key FS $(k[i])} !seen[key]++'

ティア

答え1

GNU awkを使用すると、次のことができますFPAT

$ awk -v c='2,6' -v FPAT='([^|]*)|("[^"]*")' 'BEGIN{split(c,k,",")} {key=""; for (i in k) key=key RS $(k[i])} !seen[key]++' file
3|XX|""|2022-04-05T21:39:22.899Z|2022-04-05T21:37:59Z|X7

このように二重引用符を入れ子にできる場合は、"foo""bar"FPAT割り当てを次のように変更してください。FPAT='[^|]*|("([^"]|"")*")'

バラよりawkを使用してcsvを効率的に解析する最も強力な方法は何ですかより多くの情報を知りたいです。

答え2

awkのようなものを使ってこれを行うことができます。ミラー

mlr --csv --fs '|' --implicit-csv-header --headerless-csv-output --quote-original filter '
  key = $2.FS.$6; @seen[key] += 1; @seen[key] == 1'
' file
3|XX|""|2022-04-05T21:39:22.899Z|2022-04-05T21:37:59Z|X7

!@seen[$6]++(ミラーはすでに知っているので、正確なたとえ話を使用することは不可能に見えます。ブールに自動変換されないまた、後増演算子でもありません。 )

関連情報