
Lo siento, soy muy nuevo en Linux y no estoy seguro de la capacidad de bash para lo que quiero lograr.
Quiero fusionar los valores de la columna 2 si los valores de la columna 1 y la columna 3 son idénticos. En este caso, si hay las mismas descripciones de error y el mismo comerciante, quiero fusionar los campos RefNo por coma.
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
Gastos esperados:
Error Desc|RefNo|Merchant
===================================
Category code invalid|03077,09877|merchanta
Invalid ID|12345|merchanta
Invalid ID|07323,03523|merchantc
No valid reason|78653|merchantb
Encontré publicaciones similares, pero están eliminando duplicados y no quiero eliminar ni fusionar la columna 2. Mantener filas únicas basadas en información de 2 de tres columnas.
Respuesta1
Con GNU datamash
podrías hacer:
datamash -t'|' groupby 1,3 collapse 2 < <(tail -n+3 file)
Producción:
Category code invalid|merchanta|03077,09877
Invalid ID|merchanta|12345
Invalid ID|merchantc|07323,03523
No valid reason|merchnatb|78653
Esto agrupa el primer y tercer campo y colapsa los valores del segundo campo. Se tail -n+3
utiliza para omitir las dos líneas de encabezado.
Podrías usar awk
para intercambiar la segunda y tercera columna del resultado y head
agregar las líneas de encabezado:
{
head -n2 file
datamash -t'|' groupby 1,3 collapse 2 < <(tail -n+3 file) |
awk 'BEGIN{OFS=FS="|"}{print $1,$3,$2}'
}
Producción:
Error Desc|RefNo|Merchant
===================================
Category code invalid|03077,09877|merchanta
Invalid ID|12345|merchanta
Invalid ID|07323,03523|merchantc
No valid reason|78653|merchnatb
Respuesta2
Probablemente estoy pasando por alto algo (probablemente sea posible acortarlo), pero esto funciona:
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
}
}
}
}'