我正在尝试使用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
我希望将File 2的第一列添加到File1中的信息中。我希望它匹配两个文件的第一列,但忽略“_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
答案 0 :(得分: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命令)。
答案 1 :(得分: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";
}