2

我正在尝试使用 awk 合并 2 个文件。第一个文件看起来像这样

exm-IND1-200449980  1   202183358
exm-IND1-201453487  1   203186865
exm-IND10-102817747 10  102827758

文件 2 看起来像这样

exm-IND1-200449980_ver3 -0.0676 0.9988
exm-IND1-201453487_ver1 0.0845  0.0163
exm-IND10-102817747_ver3    -0.1154 0.5166

我想将文件 2 的第一列添加到文件 1 中的信息中。我希望它匹配两个文件的第一列,但忽略“_ver3”或“_ver1”字段。我不能在需要时删除这些信息。

我以为 grep 会找到不完全匹配的,但是当我尝试时

grep exm-INDI1-200449980_ver3 file1

什么都没有返回

我试过了

awk 'NR==FNR{a[$1]=$0; next;}$1 in a {print a[$1]" "$1" "$2" "$3}' file2 file1 > file3

但它没有给我任何输出,我认为是因为它只搜索完全匹配?

文件 2 有约 16,000 行,文件 1 有约 1,000,000 行。

我正在寻找的输出将是这样的,

exm-IND1-200449980 1 202183358 exm-IND1-20449980_ver3
exm-IND1-201453487 1 203186865 exm-IND1-201453487_ver1
4

2 回答 2

1

这应该可以解决问题:

$ awk -F'_| *' 'FNR==NR{a[$1]=$0;next}$1 in a{print a[$1],$1"_"$2}' file1 file2
exm-IND1-200449980  1   202183358 exm-IND1-200449980_ver3
exm-IND1-201453487  1   203186865 exm-IND1-201453487_ver1
exm-IND10-102817747 10  102827758 exm-IND10-102817747_ver3

确保您有足够的内存来保存,file1尽管据我估计该文件应该小于 50 兆字节,这对于过去十年制造的大多数机器来说都不是问题。如果大小确实成为问题,您应该考虑将文件拆分为块(您可以为此使用split命令)。

于 2013-09-10T08:54:45.617 回答
1

Perl 解决方案:

#!/usr/bin/perl
use warnings;
use strict;

my %f2;
open my $F2, '<', 'file2' or die $!;
while (<$F2>) {
    my ($id, $num) = split ' ', $_, 3;
    $id =~ s/_ver[0-9]+//;
    $f2{$id} = $num;
}

open my $F1, '<', 'file1' or die $!;
while (<$F1>) {
    my ($id) = split ' ', $_, 2;
    chomp;
    print $_, "\t", $f2{$id}, "\n";
}
于 2013-09-10T08:56:24.863 回答