我有2个文件。如果 file1 和 file2 的字段 1、2、4 和 5 都匹配,那么我想在输出文件中依次打印 file1 和 file2 的整行。
文件1:
sc2/80 20 . A T 86 F=5;U=4
sc2/60 55 . G T 76 F=5;U=4
sc2/68 20 . T C 71 F=5;U=4
sc2/24 24 . T G 31 F=5;U=4
文件2:
sc2/99 84 . C G 61 F=5;U=4
sc2/80 20 . A T 30 F=5;U=4
sc2/60 40 . G T 76 F=5;U=4
sc2/30 20 . T C 71 F=5;U=4
sc2/24 24 . T G 91 F=5;U=4
预期输出:
sc2/80 20 . A T 86 F=5;U=4
sc2/80 20 . A T 30 F=5;U=4
sc2/24 24 . T G 31 F=5;U=4
sc2/24 24 . T G 91 F=5;U=4
我是该领域的新手,感谢您的帮助。
答案1
您可以使用多维数组:
awk 'FNR==NR{a[$1,$2,$4,$5]=$0;next}{if(b=a[$1,$2,$4,$5]){print b;print}}' file1 file2
FNR
(文件记录数)等于NR
awk 处理第一个文件时的值。
a[$1,$2]=$0
a[$1 SUBSEP $2]=$0
与或相同a[$1"\034"$2]=$0
,并且与或($1,$2)in a
相同。($1 SUBSEP $2)in a
($1"\034"$2)in a
您也可以替换if(b=a[$1,$2,$4,$5]){print b;print}
为if(($1,$2,$4,$5)in a){print a[$1,$2,$4,$5];print}
.如果!("index" in a)
,a["index"]
就像a["index"]=""
。
答案2
我知道你说过你不想要 Perl 或 Python 解决方案,但它可能对其他人有用(如果你正在做生物信息学,你真的应该学习其中一种语言)。
perl -ane '$f=$F[0].$F[1]; print "$k{$f}$_" if $k{$f}; $k{$f}=$_;' file1 file2
解释:
该-a
选项将导致 Perl 将输入分割到@F
数组中,-n
意味着逐行读取输入文件,-e
意味着“运行我在命令行上给出的脚本”。
因此,被设置为第一个 ( ) 和第二个 ( ) 字段$f
的串联。表示将当前行 ( ) 保存为使用 key调用的散列(Perl 中的关联数组)中的值。当我们读取文件时,打印当前行以及该值(如果该值存在)。换句话说,如果我们已经看到一行具有相同的两个第一个字段,请打印该行和当前行。$F[0]
$F[1]
$k{$f}=$_
$_
k
$f
$k{$f}
答案3
您想打印两个文件的交集而不重新排序它们(所以它不是一个集合交集)?我会抬头看字符串相似度算法并将每一行视为一个字母。您需要修改算法来跟踪哪些字母(行)相同,哪些不同。最大的问题是顺序很重要,但位置却不重要。此外,您可能会发现通过重写数据以删除您不关心的字段来管理数据更容易。 (或者编写一个忽略这些字段的比较函数。)
你考虑过Python还是Perl吗?我听说它们在生物信息学领域很受欢迎。这看起来真的像是一个编程任务。
答案4
如果您可以保证每个文件都应该具有唯一的条目。通过连接文件对文件进行排序sort -u
。再次排序-u
,然后搜索重复的条目。
我会写这个小剧本,但我不能凭自己的想法去做。但考虑到我的方法,这应该不难。
现在我面前有一个控制台。干得好:
rm -rf all; sort -u file1 > all; sort -u file2 >> all
sort all | uniq --all-repeated=separate -w 32
如果file1
file2
已经排序并且不包含重复的条目,您可以使用以下命令:
sort -m file1 file2 | uniq --all-repeated=separate -w 32
哦,看起来这并不完全是你问的,因为我比较了整行。也许其他人会发现这很有用。