效率低下的代码:比较来自不同文件awk或perl的不同列的组合?

时间:2013-10-14 17:12:14

标签: python perl bash awk

我有两个文件,我想将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?谢谢!

3 个答案:

答案 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以进行实际乘法。

相关问题