我有以下格式的文件
abc|1
def|2
abc|8
def|3
abc|5
xyz|3
我需要在第一列中按这些单词进行分组,并将第二列的值相加。例如,此文件的输出应为
abc|14
def|5
xyz|3
说明:word" abc"的相应值通过添加这些数字,总和为14,输出变为" abc | 14"。同样,对于单词" def",相应的值为2和3.总结这些,最终输出为" def | 5"。
非常感谢您的帮助:)
我尝试了以下命令
awk -F "|" '{arr[$1]+=$2} END {for (i in arr) {print i"|"arr[i]}}' filename
我发现的另一个命令是
awk -F "," 'BEGIN { FS=OFS=SUBSEP=","}{arr[$1]+=$2 }END {for (i in arr) print i,arr[i]}' filename
两者都没有向我显示预期的结果。虽然我也对这些命令的工作也有疑问。
答案 0 :(得分:3)
我将添加一个答案来修复您的排序问题,在您的Awk
逻辑中,您不需要使用sort
/ uniq
管道输出{ {1}},但在Awk
本身处理。
参考GNU Awk
Using Predefined Array Scanning Orders with gawk
,您可以使用Awk
变量(PROCINFO["sorted_in"]
特定的)来控制gawk
对最终输出进行排序的方式。
参考以下部分,
Awk
按索引按升序排序作为字符串进行比较;这是最基本的一种。 (在内部,数组索引始终是字符串,因此对于@ind_str_asc
,索引为a[2*5] = 1
而不是数字10
。)
所以在10
子句中的要求中使用它只需要做,
END
完整的命令,
END{PROCINFO["sorted_in"]="@ind_str_asc"; for (i in unique) print i,unique[i]}
答案 1 :(得分:2)
简称GNU datamash解决方案:
datamash -s -t\| -g1 sum 2 < filename
输出:
abc|14
def|5
xyz|3
-t\|
- 字段分隔符
-g1
- 第1栏分组
sum 2
- 总结第二列的值
答案 2 :(得分:1)
awk -F\| '{ arry[$1]+=$2 } END { asorti(arry,arry2);for (i in arry2) { print arry2[i]"|"arry[arry2[i]]} }' filename
您的初始解决方案应该与排序问题分开。使用asorti函数将索引从arry排序到arry2,然后在循环中处理它们。