我有三个文件
A.txt
DRR033612 184474
DRR033613 232882
DRR033614 66017
DRR033615 189965
DRR033616 118663
DRR029180 8439
B.txt
DRR033615 1
DRR033616 3
C.txt
DRR033615 5
DRR029180 10
DRR033612 20
我要使用以下awk命令进行总结的:
cat *.txt | awk 'BEGIN{FS=OFS="\t"}{unique[$1]=(unique[$1] FS $2); next}END{for (i in unique) print i,unique[i]}'
我基本上是根据第一列加入文件。 A.txt
包含所有项目。
不幸的是,该命令无法按照我想要的方式工作,即,20
行的值DRR033612 20
没有写在正确的字段中。
这是我的输出:
DRR033614 66017
DRR029180 8439 10
DRR033615 189965 1 5
DRR033616 118663 3
DRR033612 184474 20
DRR033613 232882
这是我想要的输出:
DRR033614 66017
DRR029180 8439 10
DRR033615 189965 1 5
DRR033616 118663 3
DRR033612 184474 20
DRR033613 232882
此外,我希望所有空单元格都被0
替换。
答案 0 :(得分:2)
对于真正的多维数组和ARGIND,使用GNU awk:
$ cat tst.awk
{ vals[$1][ARGIND] = $2 }
END {
for (key in vals) {
printf "%s", key
for (fileNr=1; fileNr<=ARGIND; fileNr++) {
printf "\t%d", vals[key][fileNr]
}
print ""
}
}
$ awk -f tst.awk A.txt B.txt C.txt
DRR033614 66017 0 0
DRR029180 8439 0 10
DRR033615 189965 1 5
DRR033616 118663 3 0
DRR033612 184474 0 20
DRR033613 232882 0 0
答案 1 :(得分:2)
在辅助函数中带有join
$ function j() { join -a1 -e0 -o1.1,1.2,"$3"2.2 <(sort $1) <(sort $2); }
$ j <(j file1 file2) file3 1.3, | column -t
DRR029180 8439 0 10
DRR033612 184474 0 20
DRR033613 232882 0 0
DRR033614 66017 0 0
DRR033615 189965 1 5
DRR033616 118663 3 0
这是通过密钥排序的,您可以恢复第一个文件的原始顺序,但是在您的预期输出中似乎不是这样。
答案 2 :(得分:1)
也许明天我会花时间写一个适当的解释,但这应该可以解决问题:
awk 'BEGIN { FS = OFS = "\t" }\
{ if (ARGIND != previousArg) {
previousArg = ARGIND;
for (i in unique) { unique[i] = (unique[i] FS) }}
unique[$1]=(unique[$1] $2); next
}
END {
for (i in unique) print i,gensub(/\t\t/, "\t0\t", "g", unique[i])
}' *.txt
答案 3 :(得分:0)
GNU awk
解决方案:
awk -v OFS='\t' \
'{ all[FILENAME][$1] = $2 }
END{
for (i in all["A.txt"]) {
r = i OFS all["A.txt"][i];
r = r OFS int(all["B.txt"][i]) OFS int(all["C.txt"][i]);
print r
}
}' A.txt B.txt C.txt
输出:
DRR033614 66017 0 0
DRR029180 8439 0 10
DRR033615 189965 1 5
DRR033616 118663 3 0
DRR033612 184474 0 20
DRR033613 232882 0 0