
죄송합니다. 저는 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를 제거하고 병합하고 싶지 않습니다. 3개 열 중 2개 열의 정보를 기반으로 고유한 행 유지.
답변1
GNU를 사용하면 datamash
다음을 수행할 수 있습니다.
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
}
}
}
}'