如何在Linux中使用join合并不等长(内部连接)的以空格分隔的文件?

时间:2019-07-02 08:41:19

标签: linux join

我有一个简单的问题:我有一个空格分隔的文件,想从另一个空格分隔的文件中添加一列,但是第二个文件较长。我想执行内部联接(因此仅添加列而不是行)。我想用linux join来做(出于效率考虑)。我曾经看到过类似的问题,但是由于我只是一个初学者,所以我无法提取所需的信息并将其应用于我的案子。

我删除了标头,并在键列(两个文件的第一列)上进行了排序。我检查了重复的钥匙(没有钥匙)。

join -1 1 -1 1 <(sort -k1 file1) <(sort -k1 file2) > file3

File 1:
rs1248851 C 655 0.7666 -0.8358 0.4033
rs1248857 G 654 1.069 0.4283 0.6684
rs1248860 G 656 1.052 0.3234 0.7464
rs12488651 G 652 1.246 1.343 0.1792
rs1248865 C 649 0.7419 -0.9125 0.3615
rs1248866 C 649 0.7696 -0.8053 0.4207
rs1248868 C 649 0.7717 -0.8317 0.4056
rs1248869 T 647 0.7878 -0.766 0.4437

File 2:
rs1248851 G
rs1248857 A
rs1248858 C
rs1248859 C
rs1248860 A
rs1248861 T
rs12488651 T
rs1248865 G
rs1248866 G
rs1248867 G
rs1248868 T
rs1248869 C

Expected result File 3:
rs1248851 C 655 0.7666 -0.8358 0.4033 G
rs1248857 G 654 1.069 0.4283 0.6684 A
rs1248860 G 656 1.052 0.3234 0.7464 A
rs12488651 G 652 1.246 1.343 0.1792 T
rs1248865 C 649 0.7419 -0.9125 0.3615 G
rs1248866 C 649 0.7696 -0.8053 0.4207 G
rs1248868 C 649 0.7717 -0.8317 0.4056 T
rs1248869 T 647 0.7878 -0.766 0.4437 C


Actual resulting error message:
join: /dev/fd/63:5: is not sorted: rs1248865 C 649 0.7419 -0.9125 0.3615
join: /dev/fd/62:8: is not sorted: rs1248865 G

2 个答案:

答案 0 :(得分:0)

不确定您使用join的逻辑或它为什么抱怨,但是...

awk 'NR==FNR{a[$1]=$0};NR!=FNR{if($1 in a){print a[$1],$2}}' file1 file2
rs1248851 C 655 0.7666 -0.8358 0.4033 G
rs1248857 G 654 1.069 0.4283 0.6684 A
rs1248860 G 656 1.052 0.3234 0.7464 A
rs12488651 G 652 1.246 1.343 0.1792 T
rs1248865 C 649 0.7419 -0.9125 0.3615 G
rs1248866 C 649 0.7696 -0.8053 0.4207 G
rs1248868 C 649 0.7717 -0.8317 0.4056 T
rs1248869 T 647 0.7878 -0.766 0.4437 C

让我们打破僵局; NR(所有输入中的记录号)与FNR(文件记录号)匹配时,我们将第一行的条目作为索引将每一行保存到一个数组中。

当我们到达第二个文件,并且在我们先前创建的数组中可以找到它的第一列时,我们先打印第一个文件中的行,然后打印第二个文件中的第二列。

答案 1 :(得分:0)

Linux上的join命令似乎更冗长,但仍会生成具有预期结果的file3文件。在MacOS上join不会抱怨。

如果您仍然想使用其他东西,可以尝试根据file2中存在的键过滤file1,如下所示:

for i in `cut -f1 -d' ' file1`; do grep $i file2 >> file2.filtered; done;

然后使用您已经拥有的原始join

join -1 1 -1 1 <(sort -k1 file1) <(sort -k1 file2.filtered) > file3