我有一个CSV文件,我想从中提取一些信息:对于一个列中的每个不同值,我想计算另一列中相应值的总和。最后,我可以用Python做,但我相信使用awk
可以有一个简单的解决方案。
这可能是CSV文件:
2 1:2010-1-bla:bla 1.6
2 2:2010-1-bla:bla 1.1
2 2:2010-1-bla:bla 3.4
2 3:2010-1-bla:bla -1.3
2 3:2010-1-bla:bla 6.0
2 3:2010-1-bla:bla 1.1
2 4:2010-1-bla:bla -1.0
2 5:2010-1-bla:bla 10.9
我想得到:
1 1.6
2 4.5
3 5.8
4 -1.0
5 10.9
目前,我只能提取:
a)第一列的值:
awk -F ' ' '{print $(2)}' MyFile.csv | awk -F ':' '{print $(1)}'
然后得到:
1
2
2
3
3
3
4
5
b)并且值等于,例如,1.1
在最后一列中:
awk -F ' ' '{print $(NF)}' MyFile.csv | awk '$1 == 1.1'
然后得到:
1.1
1.1
我无法同时提取我感兴趣的列,这可能最终会帮助我。这是一个示例输出,可以简化总和的计算(我不知道):
1 1.6
2 1.1
2 3.4
3 -1.3
3 6.0
3 1.1
4 -1.0
5 10.9
编辑:感谢Elenaher,我们可以说输入是上面的文件。
答案 0 :(得分:12)
$ awk -F"[: \t]+" '{a[$2]+=$NF}END{for(i in a ) print i,a[i] }' file
4 -1
5 10.9
1 1.6
2 4.5
3 5.8
答案 1 :(得分:4)
这假设您拥有之前显示的两列:1 1.1
BEGIN {
last = "";
sum = 0;
}
{
if ($1 != last) {
if (last != "") {
print last " " sum;
}
sum = 0;
last = $1;
}
sum = sum + $2
}
END {
print last " " sum;
}
答案 2 :(得分:2)
因此,假设您的输入如下:
unique_col, to_sum
1.3, 1 2 3
1.3, 5 6 7
1.4, 2 3 4
然后这应该可以解决问题:
$ awk -F, '{ if (seen[$1] == "") { split($2, to_sum, " "); seen[$1] = 0; for (x in to_sum) seen[$1] += to_sum[x]; }} END { for (x in seen) { if (x != "") { print x " " seen[x]; }}}' < input
1.3 6
1.4 9
答案 3 :(得分:1)
对于您的上一个问题,您可以使用split
并同时显示两列:
cat filename | awk '{split($2,tab,":"); id = tab[1]; print id " -> " $3;}'
打印:
1 -> 1.6
2 -> 1.1
2 -> 3.4
3 -> -1.3
3 -> 6.0
3 -> 1.1
4 -> -1.0
5 -> 10.9
要获得完整的结果,您可以使用:
awk -F, '{ split($1,line," "); split(line[2],tab,":"); id=tab[1]; if (sums[id]=="") {sums[id] = 0;} sums[id]+=line[3];} END {for (i=1;i<=length(sums);i++) print i " -> "sums[i]}' < test
打印:
1 -> 1.6
2 -> 4.5
3 -> 5.8
4 -> -1
5 -> 10.9
答案 4 :(得分:0)
{
b=$2; # assign column 2 to the variable 'b'
sub( /:.*/, "", b); # get rid of everything after the first colon in b
results[b] += $3
}
END { for (result in results )print result " " results[result] }
答案 5 :(得分:0)
如果Perl是一个选项:
perl -F'(\s+|:)' -lane '$h{$F[2]} += $F[-1]; END{print "$_ $h{$_}" for sort keys %h}' file
输出:
1 1.6
2 4.5
3 5.8
4 -1
5 10.9
使用以下命令行选项:
-n
循环输入文件的每一行-l
在处理之前删除换行符,然后将其添加回来-a
autosplit模式 - 将输入行拆分为@F
数组。默认为在空格上拆分。 -e
执行perl代码-F
autosplit修饰符,在这种情况下分割颜色或一个或多个空格 @F
是每行中的单词数组,从$F[0]
开始编制索引
$F[-1]
是最后一个字
将结果存储在哈希%h
中
在END处,遍历散列的排序键
打印每个元素$_
和哈希值$h{$_}