
類似した内容の CSV ファイルが大量にあります。値は通常、コンマで区切られており、次のようになります。
product_a, domestic, 500
product_a, abroad, 15
product_b, domestic, 313
product_b, abroad, 35
product_c, domestic, 411
product_c, abroad, 84
product_d, domestic, 25
product_d, abroad, 2
...
私が AWK を使って実現しようとしているのは (SED はそのような操作に適したツールではないと思うのですが、私は Linux の比較的新しいユーザーなので...)、各積 (列 1) の合計を列番号 2 として挿入することです。次のようにできます。
awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' filename
これらの値(合計)を取得するには
product_a, 515
product_b, 348
product_c, 495
product_d, 27
...
しかし、次のような形式で、元のファイルの 2 番目の列として挿入する方法がまだわかりません。
product_a, 515, domestic, 500
product_a, 515, abroad, 15
product_b, 348, domestic, 313
product_b, 348, abroad, 35
product_c, 495, domestic, 411
product_c, 495, abroad, 84
product_d, 27, domestic, 25
product_d, 27, abroad, 2
...
最近、sed と awk を少し使用していますが、試行すると通常エラーが発生します (例: スカラー値を配列として使用しようとしました)。
行の順序は問題ではありませんが、回答をバッチ ファイル コマンドとして使用できると思います。
$ for f in *.csv; do
That Shiny Enigmatic Command > tmp && mv tmp $f
done
編集
@KM に感謝します。3 ステップでやりたいことができるようになりました。
1ステップ:
$ for f in *.csv; do
awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' $f | sort > sum$f
done
ステップ2:
$ for f in [^sum]*.csv; do
join -t ',' $f sum$f | awk -F, '{print $1"," $4"," $2"," $3}' > tmp && mv tmp $f;
done
最終的にはただrm sum*.*
。ターミナルから 1 つのコマンドとして実行する方法はありますか? または、ターミナルの外部で実行する方法はありますか?
答え1
合計を というファイルに保存しsum
、ソートする
awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' filename | sort > sum
cat sum
product_a, 515
product_b, 348
product_c, 495
product_d, 27
2 つのファイルを結合し、最初のファイルの最初の列と 2 番目のファイルの最初の列 (「キー」と考えてください) をパイプして、フィールド区切り文字 ( )をawk
使用して並べ替えられた列を出力します。,
-F
そして出力フィールドセパレータ(-OFS
)として
join -t ',' -1 1 -2 1 filename sum | awk -F, -OFS=, {'print $1,$4,$2,$3}'
product_a, 515, domestic, 500
product_a, 515, abroad, 15
product_b, 348, domestic, 313
product_b, 348, abroad, 35
product_c, 495, domestic, 411
product_c, 495, abroad, 84
product_d, 27, domestic, 25
product_d, 27, abroad, 2