
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 datamash
kö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+3
wird verwendet, um die beiden Kopfzeilen zu überspringen.
Sie könnten beispielsweise awk
die zweite und dritte Spalte der Ausgabe vertauschen und head
die 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
}
}
}
}'