使用awk匹配两文件追加列时如何保留无匹配行?
解决AWK匹配双文件时保留无匹配行的问题
你现在的问题是用AWK匹配两个文件时,只输出了有匹配的行,丢失了file1里没有对应记录的行对吧?其实只需要调整一下逻辑,不管有没有匹配都输出file1的行,有匹配的话就追加对应内容就行。
先看你的原始文件内容:
file1.txt
1 101 111 . BCX 123 1 298 306 . CCC 234 1 299 305 . DDD 345
file2.txt
1 101 111 BCX P1@QQQ 1 299 305 DDD P2@WWW
你的目标是:有匹配的行追加;匹配内容,无匹配的行原样输出。
你之前的命令只在k in a时才打印,所以没匹配的行就被跳过了。我们修改一下逻辑,不管有没有匹配都先打印原行,有匹配的话再追加对应的内容(注意要加上你要的分号分隔符):
NR==FNR{ a[$1,$2,$3,$4]=$5; next } { s=SUBSEP k=$1 s $2 s $3 s $5 # 这里要注意:file2的第4列是BCX/DDD,对应file1的第5列,所以这个键是对的 printf "%s", $0 if (k in a) { print ";" a[k] } else { print "" } }
执行这个命令后,就能得到你想要的输出:
1 101 111 . BCX 123;P1@QQQ 1 298 306 . CCC 234 1 299 305 . DDD 345;P2@WWW
简单解释一下逻辑:
- 先处理file2.txt(
NR==FNR时):把$1,$2,$3,$4作为键,$5(也就是P1@QQQ这类内容)作为值存入数组a。 - 处理file1.txt时:
- 先构造和file2对应的键
k(用file1的$1、$2、$3、$5,因为file2的$4是基因名,对应file1的$5) - 先打印file1的当前行内容(用
printf "%s", $0是为了不自动换行,方便后续追加内容) - 如果键
k存在于数组a中,就打印分号加对应的值;否则直接打印换行,保留原行内容。
- 先构造和file2对应的键
另外,你之前的命令里输出是用空格分隔,现在改成了分号,这个是按照你的期望输出调整的,要是需要其他分隔符直接修改即可。
内容的提问来源于stack exchange,提问作者bapors
相关产品推荐
相关产品推荐

