我是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";
}
}
感谢您提供的任何帮助,
答案 0 :(得分: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";
}
除此之外,您可能希望使用%file2Hash
声明my
,以便重新启用strict
。
答案 1 :(得分:1)
哈希中的键必须是唯一的。如果file1中的键是唯一的,请使用file1创建哈希。如果密钥在任一文件中都不是唯一的,则必须使用更复杂的数据结构:数组的散列,即在每个唯一密钥上存储多个值。
答案 2 :(得分:-1)
我假设FILE1.txt中的每个键都是唯一的,并且每个唯一键在FILE2.txt中至少有一个对应的行。
您的方法非常接近您的需求,您应该使用FILE1.txt来创建哈希(如前所述here)。
以下内容应该有效:
#!/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;