我收到这样的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
答案 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
。