0

私はPerlにかなり慣れていないので、うまくいけば、これで簡単に解決できます。

キーに基づいて2つのファイルを結合しようとしています。問題は、返される値ではなく複数の値があることです。ハッシュをループして、取得できる値をさらに1〜10個取得する方法はありますか?

例:

ファイル入力1:

12345|AA|BB|CC
23456|DD|EE|FF

ファイル入力2:

12345|A|B|C
12345|D|E|F
12345|G|H|I
23456|J|K|L
23456|M|N|O
32342|P|Q|R

最後のファイルを入れた理由は、2番目のファイルには不要な値がたくさんあるのに、ファイル1にはすべての値が必要だからです。私が望む結果は次のようなものです:

必要な出力:

12345|AA|BB|CC|A|B|C
12345|AA|BB|CC|D|E|F
12345|AA|BB|CC|G|H|I
23456|DD|EE|FF|J|K|L
23456|DD|EE|FF|M|N|O

添付されているのは、私が現在使用しているコードです。次のような出力が得られます。

私が得ている出力:

12345|AA|BB|CC|A|B|C
23456|DD|EE|FF|J|K|L

これまでの私のコード:

#use strict; 
#use warnings; 

open file1, "<FILE1.txt"; 
open file2, "<FILE2.txt"; 

while(<file2>){

    my($line) = $_; 
    chomp $line; 
    my($key, $value1, $value2, $value3) = $line =~ /(.+)\|(.+)\|(.+)\|(.+)/; 
    $value4 = "$value1|$value2|$value3"; 
    $file2Hash{$key} = $value4; 
} 

while(<file1>){ 

    my ($line) = $_; 
    chomp $line; 
    my($key, $value1, $value2, $value3) = $line =~/(.+)\|(.+)\|(.+)\|(.+)/; 

    if (exists $file2Hash{$key}) {

        print $line."|".$file2Hash{$key}."\n";
    } 
    else {
        print $line."\n";
    } 
} 

あなたが提供するかもしれないどんな助けにも感謝します、

4

3 に答える 3

2

あなたの全体的な考えは健全です。ただし、file2では、すでに定義したキーが見つかった場合は、それを新しい値で上書きします。これを回避するために、配列(-ref)をハッシュ内に格納します。

したがって、最初のループでは、次のことを行います。

push @{$file2Hash{$key}}, $value4; 

これ@{...}は、配列の逆参照構文です。

2番目のループでは、次のことを行います。

if (exists $file2Hash{$key}){
  foreach my $second_value (@{$file2Hash{$key}}) {
    print "$line|$second_value\n";
  }
} else {
  print $line."\n";
}

それを超えて、再アクティブ化できるようにで宣言%file2Hashすることをお勧めします。mystrict

于 2012-09-11T21:13:33.260 に答える
1

ハッシュ内のキーは一意である必要があります。file1のキーが一意である場合は、file1を使用してハッシュを作成します。どちらのファイルでもキーが一意でない場合は、より複雑なデータ構造を使用する必要があります。配列のハッシュ、つまり、一意のキーごとに複数の値を格納します。

于 2012-09-11T21:12:43.430 に答える
-1

FILE1.txtの各キーは一意であり、一意の各キーにはFILE2.txtに少なくとも1つの対応する行があると想定しています。

その場合、アプローチは必要なものに非常に近くなります。FILE1.txtを使用してハッシュを作成する必要があります(すでにここで説明したように)。

以下が機能するはずです。

#!/usr/bin/perl

use strict;
use warnings;

my %file1hash;

open file1, "<", "FILE1.txt" or die "$!\n";
while (<file1>) {
    my ($key, $rest) = split /\|/, $_, 2;
    chomp $rest;
    $file1hash{$key} = $rest;
}
close file1;

open file2, "<", "FILE2.txt" or die "$!\n";
while (<file2>) {
    my ($key, $rest) = split /\|/, $_, 2;
    if (exists $file1hash{$key}) {
        chomp $rest;
        printf "%s|%s|%s\n", $key, $file1hash{$key}, $rest;
    }
}
close file2;

exit 0;
于 2012-09-11T21:26:46.590 に答える