我有两个文件,我想将file1中的第2列与file2中的第NF列匹配。如果它们匹配,我想从file2输出整行,另外还有来自file1的第5列和来自文件1的第5列,以及来自文件2的第NF-2列。文件有不同的长度。
我有以下两种文件类型:
文件1
xx name1 1 we freq1
xy name2 2 wer freq2
xz name3 3 werf freq3
file2的
..... value1 cv name1
..... value4 cvb name4
..... value3 cvb name3
..... value1 vbn name5
期望的输出
..... value1 cv name1 freq1 (freq1*value1)
..... value3 cvb name3 freq3 (freq3*value3)
我试过用awk做这件事。
awk'FNR == NR {两[$ 0] ++; next} {for(i in two){split(i,one);如果 (one [2] == $ NF)打印$ 0,一[5],$(NF-2)* one [5]}}'file1 file2> file3的
它有效,但效率极低,一段时间后我的comp崩溃了。 这些文件大约每行100,000行。也许我应该使用perl或python这个?或者有没有办法读取文件2?谢谢!
答案 0 :(得分:3)
听起来最好的方法是将file1
中相关列(2和5)的所有读入哈希值,然后只需处理file2
行线。
如果哈希使用file1
第2列作为键,则可以使用file2
的最后一列的值对其进行索引,以查看另一个文件中是否存在相应的值。
然后,所有必要的是使用哈希元素中的数据打印file2
记录中的值以及计算值。
该程序演示。变量名称有点模糊,因为你没有给你的问题中的字段赋予意义,所以我所能做的就是引用文件和列号。
我必须输出string*string
而不是实际产品,因为您的数据没有数值。
use strict;
use warnings;
use autodie;
open my $fh1, '<', 'file1';
my %file1;
while (<$fh1>) {
my ($f1_2, $f1_5) = (split)[1,4];
$file1{$f1_2} = $f1_5;
}
open my $fh2, '<', 'file2';
while (<$fh2>) {
my @f2_rec = split;
my ($f2_nm2, $f2_n) = @f2_rec[-3,-1];
if (my $f1_5 = $file1{$f2_n}) {
print join(' ', @f2_rec, $f1_5, "$f1_5*$f2_nm2"), "\n";
}
}
<强>输出强>
..... value1 cv name1 freq1 freq1*value1
..... value3 cvb name3 freq3 freq3*value3
答案 1 :(得分:3)
您只需要:
awk 'NR==FNR{a[$2]=$NF;next} $NF in a{print $0, a[$NF], a[$NF] * $(NF-2)}' file1 file2
e.g:
$ cat file1
xx name1 1 we 3
xy name2 2 wer 5
xz name3 3 werf 7
$ cat file2
..... 2 cv name1
..... 4 cvb name4
..... 6 cvb name3
..... 8 vbn name5
$ awk 'NR==FNR{a[$2]=$NF;next} $NF in a{print $0, a[$NF], a[$NF] * $(NF-2)}' file1 file2
..... 2 cv name1 3 6
..... 6 cvb name3 7 42
答案 2 :(得分:2)
perl -ane'
BEGIN{ open($f,shift)||die$!; %h = (%h, (split)[1,4]) while <$f> }
$fq = $h{$F[-1]} or next;
s|$| sprintf(" %s (%s)", $fq, "$fq*$F[-3]") |e;
print;
' file1 file2 > file3
表示为独立脚本:
#!/usr/bin/perl
use strict; use warnings;
my %frequencies;
my $frequency_file = shift @ARGV;
open my $fh, "<", $frequence_file or die "Can't open $frequency_file: $!";
while (<$fh>) {
my (undef, $name, undef, undef, $freq) = split;
$frequencies{$name} = $freq;
}
while (<>) {
my @fields = split;
my ($value, $name) = @fields[-3, -1];
next if not exists $frequencies{$name};
my $freq = $frequencies{$name};
print join(" ", @fields, $freq, "($freq * $value)"), "\n";
}
输出
..... value1 cv name1 freq1 (freq1*value1)
..... value3 cvb name3 freq3 (freq3*value3)
删除"$fq*$F[-3]"
的双qoutes以进行实际乘法。