是否可以根據兩列的複合唯一值合併行

是否可以根據兩列的複合唯一值合併行

抱歉,我對 Linux 很陌生,我不確定 bash 是否能夠實現我想要實現的目標。

如果第 1 列和第 3 列值相同,我想合併第 2 列值。在這種情況下,如果有相同的錯誤描述和相同的商家,我想透過逗號合併RefNo欄位。

Error Desc|RefNo|Merchant
===================================
Category code invalid|03077|merchanta
Category code invalid|09877|merchanta
Invalid ID|12345|merchanta
Invalid ID|07323|merchantc
Invalid ID|03523|merchantc
No valid reason|78653|merchantb

預期結果:

Error Desc|RefNo|Merchant
===================================
Category code invalid|03077,09877|merchanta
Invalid ID|12345|merchanta
Invalid ID|07323,03523|merchantc
No valid reason|78653|merchantb

我發現了類似的帖子,但它正在刪除重複項,而我不想刪除並合併第 2 列。 根據三列中的兩列中的信息保留唯一行

答案1

使用 GNUdatamash你可以這樣做:

datamash -t'|' groupby 1,3 collapse 2 < <(tail -n+3 file)

輸出:

Category code invalid|merchanta|03077,09877
Invalid ID|merchanta|12345
Invalid ID|merchantc|07323,03523
No valid reason|merchnatb|78653

這會對第一個和第三個欄位進行分組,並折疊第二個欄位的值。用於tail -n+3跳過兩個標題行。

您可以用來awk交換輸出的第二列和第三列並head新增標題行:

{
  head -n2 file
  datamash -t'|' groupby 1,3 collapse 2 < <(tail -n+3 file) | 
    awk 'BEGIN{OFS=FS="|"}{print $1,$3,$2}'
}

輸出:

Error Desc|RefNo|Merchant
===================================
Category code invalid|03077,09877|merchanta
Invalid ID|12345|merchanta
Invalid ID|07323,03523|merchantc
No valid reason|78653|merchnatb

答案2

我可能忽略了一些東西 - 可能可以使其更短 - 但這是有效的:

awk '
    BEGIN   {   FS="|"; OFS="|" }
    NR <= 2
    NR > 2  {
                seen_desc[$1]++
                seen_merc[$3]++
                if (ref[$1,$3] == "")
                        ref[$1,$3] = $2
                else
                        ref[$1,$3] = ref[$1,$3] "," $2
            }
    END     {
                for (desc in seen_desc) {
                        for (merc in seen_merc) {
                                if (ref[desc,merc] != "") {
                                        print desc, ref[desc,merc], merc
                                }
                        }
                }
            }'

相關內容