如何使用awk比较CSV列?

时间:2016-02-25 22:03:02

标签: linux bash sorting csv awk

我收到这样的CSV:

column$1,column$2,column$
john,P,10
john,P,10
john,A,20
john,T,30
john,T,10
marc,P,10
marc,C,10
marc,C,20
marc,T,30
marc,A,10

我需要对值进行求和并显示名称和结果,但是$ 2列需要显示与值P,A,C分开的值T的总和。 输出应为:

column$1,column$2,column$3,column$4
john,PCA,40
john,T,40,CORRECT
marc,PCA,50
marc,T,30,INCORRECT

我所能做的只是从原始的csv中提取我需要的列:

    awk -F "|" '{print $8 "|" $9 "|" $4}' input.csv >> output.csv

也按正确的列排序:

sort -t "|" -k1 input.csv >> output.csv

并在csv的末尾添加一个新列:

awk -F, '{NF=2}1' OFS="|" input.csv >> output.csv

我设法总结并按列$ 1和$ 2显示总和,但我不知道如何对第2列中的不同值进行分组:

awk -F "," '{col[$1,$2]++} END {for(i in col) print i, col[i]}' file > output

2 个答案:

答案 0 :(得分:1)

Awk是面向流的。它处理输入并输出您更改的内容。它不会在文件更改中执行。

您只需要添加相应的打印

awk '{if($2 == "T") {print "MATCHED"}}'

如果你想输出超过"匹配的"你需要将它添加到打印 例如'{print $1 "|" $2 "|" $3 "|" " MATCHED"}'

或使用print $0作为上述评论。

答案 1 :(得分:0)

假设通过将“PCA”值与“T”值进行比较来确定“CORRECT”和“INCORRECT”,以下awk脚本应该可以解决这个问题:

awk -F, -vOFS=, '$2=="T"{t[$1]+=$3;n[$1]} $2!="T"{s[$1]+=$3;n[$1]} END{ for(i in n){print i,"PCA",s[i]; print i,"T",t[i],(t[i]==s[i] ? "CORRECT" : "INCORRECT")} }' inputfile

为便于阅读而分手,这就是以下内容:

awk -F, -vOFS=, '

  $2=="T" {    # match all records that are "T"
    t[$1]+=$3  # add the value for this record to an array of totals
    n[$1]      # record this name in our authoritative name list
  }

  $2!="T" {    # match all records that are NOT "T"
    s[$1]+=$3  # add the value for this record to an array of sums
    n[$1]      # record this name too
  }

  END {        # Now that we've collected data, analyse the results
    for (i in n) {  # step through our authoritative list of names
      print i,"PCA",s[i]
      print i,"T",t[i],(t[i]==s[i] ? "CORRECT" : "INCORRECT")
    }
  }

' inputfile

请注意,在awk中无法保证数组顺序,因此您的输出可能与输入的顺序不同。

如果您希望使用竖线分隔输出,请将-vOFS=,更改为-vOFS='|'

然后你可以使用:

进行排序
awk ... | sort

默认为-k1