Ist es möglich, Zeilen basierend auf den zusammengesetzten eindeutigen Werten zweier Spalten zusammenzuführen?

Ist es möglich, Zeilen basierend auf den zusammengesetzten eindeutigen Werten zweier Spalten zusammenzuführen?

Entschuldigung, ich bin ein völliger Neuling bei Linux und bin mir nicht sicher, ob Bash für das, was ich erreichen möchte, geeignet ist.

Ich möchte die Werte in Spalte 2 zusammenführen, wenn die Werte in Spalte 1 und Spalte 3 identisch sind. In diesem Fall möchte ich die RefNo-Felder per Komma zusammenführen, wenn es dieselben Fehlerbeschreibungen und denselben Händler gibt.

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

Erwartetes Ergebnis:

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

Ich habe ähnliche Beiträge gefunden, aber es werden Duplikate entfernt und ich möchte stattdessen Spalte 2 nicht entfernen und zusammenführen. Beibehalten eindeutiger Zeilen basierend auf Informationen aus zwei von drei Spalten.

Antwort1

Mit GNU datamashkönnten Sie Folgendes tun:

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

Ausgabe:

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

Dies gruppiert das erste und dritte Feld und blendet die Werte des zweiten Felds aus. Dies tail -n+3wird verwendet, um die beiden Kopfzeilen zu überspringen.

Sie könnten beispielsweise awkdie zweite und dritte Spalte der Ausgabe vertauschen und headdie Kopfzeilen hinzufügen:

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

Ausgabe:

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

Antwort2

Wahrscheinlich übersehe ich etwas – es geht wahrscheinlich auch kürzer – aber so funktioniert es:

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
                                }
                        }
                }
            }'

verwandte Informationen