grep 两个列表之间

grep 两个列表之间

我的 Linux 机器上有两个文件。第一个“list.txt”包含一个对象列表(2649 个对象),而第二个“list_interactors.txt”包含一个较短的列表,其中包含先前列表中的一些对象(719 个对象),并且对于每个对象,都有其他对象列一些关联的变量。我想获得所有对象(2649)的列表以及文件“list_interactors”中特定对象的关联变量。

例子:

文件list.txt

6tyr_A_002__________
7yer_2_009__________
3erf_1_001__________
2dr5_D_2-3__________

文件list_interactors.txt

6tyr_A_002__________    6tyr1_B    QRT54R   AAAAA
3erf_1_001__________    3erf2_B    QAEF6R   XXXXX

output.txt

6tyr_A_002__________    6tyr1_B    QRT54R   AAAAA
7yer_2_009__________
3erf_1_001__________    3erf2_B    QAEF6R   XXXXX
2dr5_D_2-3__________

我对编程语言不太实用。我尝试在这个脚本中使用 grep 函数:

grep -f list.txt list_interactors.txt

但输出是一个类似于文件“list_interactors.txt”的文件。

请问你能帮帮我吗?

答案1

$ join -a 1  <( sort list.txt ) <( sort list_interactors.txt )
2dr5_D_2-3__________
3erf_1_001__________ 3erf2_B QAEF6R XXXXX
6tyr_A_002__________ 6tyr1_B QRT54R AAAAA
7yer_2_009__________

这用于join在两个文件之间执行关系 JOIN 操作。默认情况下,第一个字段将用作连接键。

-a 1选项使join输出第一个文件中的所有行,即使第二个文件中没有匹配项(它执行“左连接”)。

输入数据join需要进行排序,我们通过sort在命令行上的两个进程替换中单独调用每个文件来完成此操作。您还可以选择对文件进行预排序。

如果您的数据是制表符分隔的,您可能需要添加-t $'\t'到命令参数的开头join。这将使输出保留现有的制表符分隔符。

>output.txt如果要将输出存储在文件中,请通过添加到命令末尾来重定向输出。

答案2

如果你想保持排序,你可以使用awk

awk '
    FNR==NR {s[$1]=$0}
    FNR!=NR {if(s[$1]) print s[$1]; else print $0}
' list_interactors.txt list.txt

输出:

6tyr_A_002__________    6tyr1_B    QRT54R   AAAAA
7yer_2_009__________
3erf_1_001__________    3erf2_B    QAEF6R   XXXXX
2dr5_D_2-3__________

答案3

$ awk 'NR==FNR{a[$1]=$0; next} {print ($1 in a ? a[$1] : $0)}' list_interactors.txt list.txt
6tyr_A_002__________    6tyr1_B    QRT54R   AAAAA
7yer_2_009__________
3erf_1_001__________    3erf2_B    QAEF6R   XXXXX
2dr5_D_2-3__________

答案4

Perl oneliner 还可以做到:

$ perl -ane ' { chomp;$s{$F[0]}=$_; } END { print "$s{$_}\n" for sort(keys(%s))  }' list.txt list_interactors.txt 
2dr5_D_2-3__________
3erf_1_001__________    3erf2_B    QAEF6R   XXXXX
6tyr_A_002__________    6tyr1_B    QRT54R   AAAAA
7yer_2_009__________

相关内容