抱歉,我对 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
}
}
}
}'