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 我想要所有值。我想要的结果是这样的:

想要的输出:

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; 

@{...}只是数组取消引用语法。

在您的第二个循环中,我们执行以下操作:

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

除此之外,您可能需要声明%file2Hashwithmy以便重新激活strict.

于 2012-09-11T21:13:33.260 回答
1

哈希中的键必须是唯一的。如果 file1 中的键是唯一的,则使用 file1 创建散列。如果任一文件中的键都不唯一,则必须使用更复杂的数据结构:数组散列,即在每个唯一键处存储多个值。

于 2012-09-11T21:12:43.430 回答
-1

我假设 FILE1.txt 中的每个键都是唯一的,并且每个唯一键在 FILE2.txt 中至少有一个对应的行。

然后,您的方法非常接近您的需要,您应该只使用 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 回答