我有3个文件:
我file1
有这样的数据:
id,name,age
1,jj,60
2,kk,45
3,ss,56
我file2
有这样的数据:
id,name,age
1,jj,60
2,kk,44
3,ss,55
4,tt,66
我file3
只有一个字段,即 id:
id
1
2
3
现在我想比较file1
&file2
中的那些 ID file3
。
输出应该是这样的:
id file1 file2
2 age=45 age=44
3 age=56 age=55
答案1
扩展paste
+awk
解决方案:
awk -F',' -v ids=$(paste -s -d'|' <(tail -n+2 file3)) \
'BEGIN{ OFS="\t"; print "id", ARGV[1], ARGV[2] }
FNR==1{ next }
NR==FNR{ if ($1 ~ "^("ids")$") a[$1$2]=$3; next }
($1$2 in a) && a[$1$2] != $3{
printf "%d\tage=%d\tage=%d\n", $1, a[$1$2], $3
}' file1 file2
输出:
id file1 file2
2 age=45 age=44
3 age=56 age=55
答案2
罗曼的回答很好,并为您提供了您所要求的确切输出。
然而,如果你仅有的需要原始数据(即没有 CSV 标题并且没有 printf 漂亮打印的格式),您可以使用paste
+ comm
+ grep
+流程替代:
$ paste <(comm -1 -3 file1 file2) <(comm -2 -3 file1 file2) |
grep -f <(sed -e 's/^/^/; s/$/,/;' file3)
2,kk,44 2,kk,45
3,ss,55 3,ss,56
解释:
comm -1 -3 file1 file2
输出 所特有的行file2
。 comm -2 -3 file1 file2
输出 所特有的行file1
。这两个命令的输出都paste
通过进程替换 给出,并连接在一起。
paste
然后, 的输出通过管道传输到 grep 中,以仅输出与 中列出的 id 匹配的行file3
。此处还使用进程替换将 file3 中列出的 ID 转换为锚定正则表达式,仅当 ID 号位于行开头且后跟逗号时,该正则表达式才匹配 ID 号。
如果您想要/需要进行进一步处理,那么做这样的事情最有用前漂亮地打印输出。