1

2 つのファイルがあり、file1 の列 2 を file2 の列 NF と一致させたいと考えています。それらが一致する場合、file2 の行全体を出力したいと思います。さらに、file1 の列 5 とファイル 1 の列 5 に、最後にファイル 2 の列 NF-2 を乗算します。ファイルの長さが異なります。

次の 2 つのファイル タイプがあります。

ファイル1

xx  name1 1 we    freq1
xy  name2 2 wer   freq2
xz  name3 3 werf  freq3

ファイル2

..... 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 { 2[$0]++; 次へ } { for (i in two) { split(i, one); if (one[2] == $NF) print $0, one[5], $(NF-2)*one[5] } }' file1 file2 > file3

それは機能しますが、非常に非効率的で、しばらくするとコンプがクラッシュします。ファイルはそれぞれ約 100,000 行です。多分私はこれにperlかpythonを使うべきですか?または、ファイル 2 も読み取る方法はありますか? ありがとう!

4

3 に答える 3

3

関連するすべての列 (2 と 5) をfile1ハッシュに読み取り、1 行ずつ処理するのが最善の方法のように思えます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
于 2013-10-14T18:21:49.923 に答える