我有大量内容相似的 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 列)的总和,作为一列插入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
...
但我仍然不知道如何将它们作为第二列插入到原始文件中,形式如下:
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
第二步:
$ 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
连接两个文件,第一个文件的第一列与第二个文件的第一列(认为“键”);将其通过管道传输到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