我需要使用 4 个字段(文件 1 的字段 1、2、4 和 5 与文件 2 的字段 1、2、4 和 5)比较两个文件 File1 和 File2(以空格分隔)。
逻辑:
如果文件 1 的第 1、2 和 4 列与文件 2 的第 1、2 和 4 列匹配,并且第 5 列不匹配,则来自文件 1 和文件 2 的行都连接起来重定向为输出。因此,输出文件仅包含 File1 和 File2 的第 1、2 和 4 列匹配而第 5 列不匹配的那些行。
文件1:
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/68 20 . T C 71 PASS N=2 F=5;U=4
sc2/24 24 . T G 31 PASS N=2 F=5;U=4
Run Code Online (Sandbox Code Playgroud)
文件2:
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
sc2/68 20 . T C 71 PASS N=2 F=5;U=4
sc2/10 24 . T G 31 PASS N=2 F=5;U=4
sc2/40 59 . T G 31 PASS N=2 F=5;U=4
sc2/24 24 . A G 38 PASS N=2 F=5;U=4
Run Code Online (Sandbox Code Playgroud)
输出:
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
Run Code Online (Sandbox Code Playgroud)
我是该领域的新手,感谢您的帮助。
您可以使用awk. 将以下内容放入脚本中script.awk:
FNR == NR {
f1[$1,$2,$4] = $0
f1_c14[$1,$2,$4] = 1
f1_c5[$1,$2,$4] = $5
next
}
f1_c14[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print f1[$1,$2,$4];
}
f1[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print $0;
}
Run Code Online (Sandbox Code Playgroud)
现在像这样运行它:
$ awk -f script.awk file1 file2
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
Run Code Online (Sandbox Code Playgroud)
该脚本的工作原理如下。此块创建 3 个数组f1,f1_c14、 和f1_c5。f1包含数组中 file1 的所有行,使用 file1 中第 1、2 和 4 列的内容进行索引。f1_c14是另一个具有相同索引(1、2 和 4 的内容)且值为 的数组1。第三个数组使用与第一个 2 相同的索引,以及文件 1 中第 5 列的值。
FNR == NR {
f1[$1,$2,$4] = $0
f1_c14[$1,$2,$4] = 1
f1_c5[$1,$2,$4] = $5
next
}
Run Code Online (Sandbox Code Playgroud)
下一个块是负责从第一文件的打印线,file1的条件下,该列的1,2,和4匹配从柱file2,AND它将onlu从打印线file1,如果第5列file1和file2不匹配。
f1_c14[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print f1[$1,$2,$4];
}
Run Code Online (Sandbox Code Playgroud)
第三个块负责打印关联行,从file2数组f1中file2的第 1、2 和 4 列的相应行开始。同样,它仅在第 5 列不匹配时才打印。
f1[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print $0;
}
Run Code Online (Sandbox Code Playgroud)
像这样运行上面的脚本:
$ awk -f script.awk file1 file2
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
Run Code Online (Sandbox Code Playgroud)
您可以使用该column命令稍微清理输出:
$ awk -f script.awk file1 file2 | column -t
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
Run Code Online (Sandbox Code Playgroud)
这利用了awk以特定方式循环文件的能力。在这里,我们循环遍历文件,当我们位于第一个文件的行上时file,我们希望从file1.
这个例子展示了FNR == NR当我们给它 2 个模拟文件时正在做什么。一个有 4 行,而另一个有 5 行:
$ awk 'BEGIN {print "NR\tFNR\tline"} {print NR"\t"FNR"\t"$0}' \
<(seq 1 4) <(seq 1 5)
NR FNR line
1 1 1
2 2 2
3 3 3
4 4 4
5 1 1
6 2 2
7 3 3
8 4 4
9 5 5
Run Code Online (Sandbox Code Playgroud)
其他街区
其他块,f1_c14[$1,$2,$4]并且f1[$1,$2,$4]仅当来自这些数组元素的值具有值时才运行。