Shell-Script

如何使用 awk 和 Pipe in Values 從管道分隔文件中刪除重複項?

  • April 7, 2022

我正在嘗試使用如何從管道分隔文件中刪除基於多個列的重複項如何基於多個動態列刪除重複項 但我發現雙引號中的值中有管道,如下所示

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

使用 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='[^|]*|("([^"]|"")*")'

有關更多資訊,請參閱whats-the-most-robust-to-efficiently-parse-csv-using-awk

您可以使用Miller以類似 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]++,因為米勒沒有自動轉換為布爾運算符或後增量運算符。)

引用自:https://unix.stackexchange.com/questions/698261