2012-09-11 1 views
0

저는 Perl에 익숙하지 않으므로 빠른 해결책이 있습니다.첫 번째 열을 기준으로 두 파일을 병합하고 각 키에 대해 여러 값을 반환합니다.

저는 키를 기반으로 두 개의 파일을 결합하려고했습니다. 문제는 반환하는 값 대신 여러 값이 있다는 것입니다. 해시를 반복하여 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 

두 번째 파일 값을 많이 가지고 있기 때문에 나는에서 그 마지막 1 점을 추가하는 듯 그 이유는 내가 원하지 않지만 파일 1 모든 값을 원합니다.

WANTED OUTPUT : 첨부

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"; 
    } 
} 

당신이 제공 할 수있는 모든 도움을 주셔서 감사합니다,

+2

그것은, 보인다! – hobbs

답변

2

귀하의 전반적인 아이디어는 확실합니다. 그러나 file2에서 이미 정의한 키를 발견하면 새 값으로 덮어 씁니다. 그 문제를 해결하기 위해 우리는 해시 안에 배열 (-ref)을 저장합니다.

그래서 첫 번째 루프에서, 우리가 할 :

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

@{...} 그냥 배열이 역 참조되는 구문을. 두 번째 루프에서

, 우리는 할 : 그 너머

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

, 당신은 그래서 당신은 strict을 활성화 할 수 있습니다 my%file2Hash를 선언 할 수 있습니다.

+0

응답 해 주셔서 감사합니다! 이것은 효과가있다! 나는 전에 얻지 못했던 모든 가치를 얻고있다! 고맙습니다! – user1258104

1

키에 해시는 고유해야합니다. file1의 키가 고유 한 경우 file1을 사용하여 해시를 만듭니다. 두 파일에서 키가 고유하지 않으면 배열의 해시, 즉 각 고유 키에 여러 값을 저장하는 등 더 복잡한 데이터 구조를 사용해야합니다.

0

FILE1.txt의 각 키는 고유하며 각 고유 키에는 FILE2.txt에 하나 이상의 해당 줄이 있다고 가정합니다.

당신의 접근 방식은 당신이 필요로하는 것에 아주 가깝습니다, 당신은 단지 FILE1.txt를 사용하여 해시를 생성해야합니다 (이미 언급 한 바와 같이 here).

다음은 작동합니다 : 당신이 딱 맞는 아이디어를 내놓았다처럼 반대 순서로 파일 1과 파일 2를 처리 할 필요가 제외

#!/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; 
관련 문제