
同様のコンテンツを含む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ユーザーだからです...)合計することです。 nr 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
合計を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番目のファイルの最初の列です(「キー」と考えてください)。これをパイプで接続し、フィールド区切り記号()を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