
申し訳ありませんが、私は 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
これは、最初のフィールドと 3 番目のフィールドをグループ化し、2 番目のフィールドの値を折りたたみます。 は、tail -n+3
2 つのヘッダー行をスキップするために使用されます。
awk
出力の 2 列目と 3 列目を入れ替え、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
}
}
}
}'