我的文件的值如下:
(X1 55) (X2 99) (X3 29) (X1 3) (X3 10)
(X1 21) (X3 11) (X1 9)
是否可以通过每行Xn
名称添加值:
(X1 58) (X2 99) (X3 39)
(X1 30) (X3 11)
我不确定最好使用哪种,awk,sed或......?我试过这个:
awk '{for (i=t=0;i<NF;) t+=$++i; $0=t}1' file
196
41
它显然将所有值加在一起,所以可能它有点复杂。
答案 0 :(得分:6)
$ awk '{
for (i=1;i<NF;i+=2) {
sum[$i]+=$(i+1)
}
ofs = ""
for (key in sum) {
printf "%s%s %d)", ofs, key, sum[key]
delete sum[key]
ofs = OFS
}
print ""
}' file
(X2 99) (X3 39) (X1 58)
(X3 11) (X1 30)
如果您关心字段的顺序,可以通过各种方式保留原始订单...
答案 1 :(得分:3)
你在这里:
echo '(X1 55) (X2 99) (X3 29) (X1 3) (X3 10)' | sed 's/[()]//g' | awk '{for( i=1; i<NF; i+=2) a[$i]+=$(i+1);} {for (keys in a ) print keys, a[keys];}'
输出:
X1 58
X2 99
X3 39
我认为这已足够接近了?
答案 2 :(得分:0)
我应该操纵FS
和RS
来紧密匹配数据。除非您使用gawk >= 4.0
并设置PROCINFO["sorted_in"]
来指定它们的遍历方法,否则awk的数组遍历是随机的。
$ awk '
NF{ x[$1] += $2 }
2==NF{
for (i in x) { printf "%s(%s %s)", sep, i, x[i]; sep = " "; }
print "";
split("",x); sep = "";
}
' RS='[\\n\\(]' FS='[ \\n]' /tmp/file.txt
(X1 58) (X2 99) (X3 39)
(X1 30) (X3 11)