使用awk查找2个文件之间的公共行

时间:2018-12-24 15:04:31

标签: awk

我有2个文本文件,分别称为“ 1”和“ 2”,如以下2个示例所示:

一个:

chr5    315038  315059  PDCD6
chr5    315039  315059  PDCD6
chr5    315035  315136  AHRR
chr5    315010  315111  AHRR
chr5    315032  315133  AHRR

两个:

chr5    315035  315059  PDCD6
chr5    315035  315136  AHRR
chr12   49314934    49315035    CCDC65

我想基于4列获取这2个文件的相似行。例如,对于文件一和文件二,预期的输出将类似于以下内容,因为这行在2个文件中(对于所有列)完全相同。

预期输出:

chr5    315035  315136  AHRR

我正在尝试使用以下命令在awk中执行此操作,但结果不是我想要的。你知道如何解决吗?

awk 'FNR==NR{a[$1$2$3$3]++;next}!a[$4$3$2$1]' one.txt two.txt > result.txt

3 个答案:

答案 0 :(得分:2)

如果您要检查完整的行本身,请尝试执行以下操作。

awk 'FNR==NR{a[$0];next} $0 in a'  one  two

答案 1 :(得分:1)

ravindersingh13所述,您可以选择awk来解决您的问题:

以下awk脚本执行相同的操作:

$ awk 'NR==FNR{a[$0]++;next} a[$0]' one two
chr5    315035  315136  AHRR

此方法不需要对文件进行排序,但是由于您将行存储在关联数组中,因此会占用更多内存。较大的内存消耗,但是对大文件(由于不需要排序)的处理速度更快。

如果您想要更直接的方法,则可以使用comm

$ comm -1 -2 <(sort one) <(sort two)
chr5    315035  315136  AHRR
  

一种工具,用于逐行比较两个排序的文件

grep使用选项-f(第一个文件将定义模式列表,grep将使用该模式列表查询第二个文件)

$ grep -f one two
chr5    315035  315136  AHRR
  

-f FILE, --file=FILE   从FILE获取模式,每行一个。如果此选项已多次使用或与-e (--regexp)选项结合使用,   搜索所有给定的模式。空文件包含零   模式,以及                 因此什么都不匹配。

答案 2 :(得分:0)

您可以尝试Perl解决方案

$ cat user10657934_one.txt
chr5    315038  315059  PDCD6
chr5    315039  315059  PDCD6
chr5    315035  315136  AHRR
chr5    315010  315111  AHRR
chr5    315032  315133  AHRR

$ cat user10657934_two.txt
chr5    315035  315059  PDCD6
chr5    315035  315136  AHRR
chr12   49314934    49315035    CCDC65

$ perl -lne ' push @{$kv{$_}} ,$ARGV ; END { for(keys %kv) { print "$_" if scalar(@{$kv{$_}}>1) } } ' user10657934_one.txt user10657934_two.txt
chr5    315035  315136  AHRR

$ perl -lne ' $kv{$_}.="$ARGV;" ; END { for(keys %kv) { print "$_" if $kv{$_}=~/;.*;/ } } ' user10657934_one.txt user10657934_two.txt
chr5    315035  315136  AHRR