次の入力CSVファイルがあります。
john,Hello my name
john,is John
katie,Whereas my
katie,name is Katie
bob,And I am Bob.
ファイルは、名前(最初の列)が連続し、テキスト(2番目の列)が論理的な順序になるようにソートされます。
最初の列を「グループ化」(SQL用語を使用)し、2番目の列を結合する標準化された方法はありますか?
私が望む出力は次のとおりです。
john,Hello my name is John
katie,Whereas my name is Katie
bob,And I am Bob.
答え1
各ブロックの長さに関する詳細な知識によって、関数のENDブロックをコピーする必要がある境界条件の小さな複雑さを処理する必要はありません。
私はこのアプローチを擁護するのではなく、Gilesが受け入れた答えを支持することです。複雑な問題を処理するときに、複雑さ(I / Oとメモリを犠牲にして)を大幅に減らすことができる代替アプローチを示すために、この問題を提起しました(これはその1つではありません)。
a
名前 インデックスブロック長の配列です。n
ブロックに残っている行数。
awk -F, '
FNR==NR {a[$1]++; next}
n {print " "$2}
!n {print; n=a[$1]}
!--n {print "\n"}
' ORS= data data
答え2
これを行う標準的なツールはありません。これはawkに適しています。 1行ずつ読み、最初のフィールドを保存し、2番目のフィールドを累積し、最初のフィールドが変更された場合に結果を印刷します。主な(マイナーな)困難は、最後の行に達したときに結果を印刷する必要があることです。
awk -F, '
1 {current = $1; sub(/^[^,]*,/,"")}
current == previous {acc = acc " " $0; next}
NR != 1 {print previous "," acc}
1 {previous = current; acc = $0}
END {if (NR) print previous "," acc}'
答え3
awk -F, '{a[$1]=a[$1]? a[$1]" "$2 : $2;}END{for (i in a)print i, a[i];}' OFS=, filename