如何使用 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 时,这两行是重复的,但由于位置 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]++'

TIA

答案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]++因为米勒有不自动转换为布尔值也不是后自增运算符。)

相关内容