从CSV文件中获取条件和

时间:2010-10-14 14:46:27

标签: csv awk

我有一个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,我们可以说输入是上面的文件。

6 个答案:

答案 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{$_}