同じキーを持つ連続した行にまたがるテキストを結合しますか?

同じキーを持つ連続した行にまたがるテキストを結合しますか?

次のような入力 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 ブロックを必要とする境界条件を処理する際のわずかな複雑さから解放されます。

私は、Gilles の受け入れられた回答を支持してこのアプローチを推奨しているわけではありません。私は単に、複雑な問題 (これはその 1 つではありません) を扱うときに、複雑さを大幅に軽減できる (I/O とおそらくメモリを犠牲にして) 代替アプローチを示すためにこれを提示しているだけです。

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

関連情報