将列从一个文件匹配到另一个文件的最快方法

时间:2017-09-12 12:55:20

标签: unix awk

我有两个文件都有超过一百万行,我想从文件1的第一列和文件2的第二列打印出匹配。

file_1

SNP_A-2131660   1   0.0021
SNP_A-1967418   2   0.0005
SNP_A-1969580   2   0.0011
SNP_A-4263484   1   0.0024
SNP_A-1978185   0   0.0014
SNP_A-4264431   0   0.0038
SNP_A-1980898   2   0.0050
SNP_A-1983139   0   0.0011

file_2

"AFFX-SNP_10000979" "rs4147951"
"AFFX-SNP_10009702" "rs2022235"
"SNP_A-2131660" "rs6425720"
"AFFX-SNP_10021569" "rs12997193"
"AFFX-SNP_10026879" "rs9933410"
"AFFX-SNP_10029725" "rs7142489"
"AFFX-SNP_10034687" "rs1350088"

matches.txt

"SNP_A-2131660" "rs6425720"

现在我正在做,但它太慢了。有更快的方法吗?

awk '{print $1}' file_1 | while read -r a; do grep -H $a file_2; done >> matches.txt

3 个答案:

答案 0 :(得分:1)

请你试试下面的awk。

awk 'FNR==NR{a[$1]=$0;next} {val=$1;gsub(/\"/,"",val)} (val in a)' file_1 file_2

如果您想将命令的输出重定向到输出文件,您可以执行>输出结尾的output.txt(或任何你喜欢的输出文件的名称)。

答案 1 :(得分:1)

使用awk,并在读取第一个文件后设置字段分隔符FS='"'

awk 'FNR==NR{a[$1];next}$2 in a' file1 FS='"' file2

# OR

awk -v q='"' 'FNR==NR{a[q $1 q];next}$1 in a' file1 file2

直到现在发布的所有解决方案都会更快,因为我们没有排序文件,替换双引号并加入它们

测试结果:

$ cat f1
SNP_A-2131660   1   0.0021
SNP_A-1967418   2   0.0005
SNP_A-1969580   2   0.0011
SNP_A-4263484   1   0.0024
SNP_A-1978185   0   0.0014
SNP_A-4264431   0   0.0038
SNP_A-1980898   2   0.0050
SNP_A-1983139   0   0.0011

$ cat f2
"AFFX-SNP_10000979" "rs4147951"
"AFFX-SNP_10009702" "rs2022235"
"SNP_A-2131660" "rs6425720"
"AFFX-SNP_10021569" "rs12997193"
"AFFX-SNP_10026879" "rs9933410"
"AFFX-SNP_10029725" "rs7142489"
"AFFX-SNP_10034687" "rs1350088"

$ awk 'FNR==NR{a[$1];next}$2 in a' f1 FS='"' f2
"SNP_A-2131660" "rs6425720"

# OR
$ awk -v q='"' 'FNR==NR{a[q $1 q];next}$1 in a' f1 f2
"SNP_A-2131660" "rs6425720"

答案 2 :(得分:0)

一种可能的工具是加入,但您需要一些预处理和一些后处理:

sort < file1 > file1_sorted
sort < file2 | sed 's/^"\([^"]*\)"/\1/' > file2_sorted
join file1_sorted file2_sorted -1 1 -2 1

给出:

SNP_A-2131660 1 0.0021 "rs6425720"