我想匹配两个文件之间的数组元素。第一个文件由六个元素组成,第二个文件由七个元素组成。
第一个文件中的前六个元素与第二个文件中的六个元素匹配。除了第二个文件中的最后一个元素外,两行相同。
如果该行与第一个文件匹配,我必须从第二个文件打印整行。
第一个文件 - errep.txt
XYZ432345 Ethiopia 2567 89 ABC P 28-Apr-14
XYZ432345 Poland 2567 98 ABC P 28-Apr-14
第二个文件 - rep.txt
XYZ432345 Ethiopia 2567 89 ABC P 28-Apr-14 No Issue
XYZ432345 Philippines 2467 92 ADC P 28-Apr-14 No Issue
期望输出
XYZ432345 Ethiopia 2567 89 ABC P 28-Apr-14 No Issue
以下是我正在尝试的代码
use strict;
use warnings;
open(OUT,"> Final Error Report.txt");
open(IN, "rep.txt");
my @values = <IN>;
close IN;
$flag=0;
$count=0;
open(IN, "errep.txt");
my @verify = <IN>;
close IN;
for my $ver (@verify) {
chomp $ver;
@elements= split("\t",$ver);
for my $rep (@values) {
chomp $rep;
@report = split("\t",$rep);
$newstring1="@elements[0 .. 5]";
$newstring2="@report[0 .. 5]";
if ($newstring1 =~/$newstring2/) {
++$count;
$flag=1;
}
if($flag==1){
$flag=0;
print OUT "$rep\n";
}
}
}
print OUT "Total Count:$count";
如果任何人可以改进这个代码非常感谢。感谢您的建议..
答案 0 :(得分:0)
&&
不是&
$code eq $code1
(不是$code =~ $code1
,进行正则表达式匹配)REPORT
中的所有行加载到数组中。目前,在外循环的第二次迭代中,<REPORT>
将立即返回undef
,因为您已经从此文件中读取了所有内容。 (或者,您可以使用seek()
来回放文件指针。)答案 1 :(得分:0)
你是什么意思匹配。这两条线并不完全匹配。你是说第一个文件中的前六个元素是否与第二个文件中的六个元素匹配?线条是否相同,除了第七个文件中的最后一个元素?
每当你说“我必须找到一个匹配”时,你首先考虑使用哈希值。如果您的文件非常大,则需要考虑使用外部数据库。
我还将使用更多现代 Perl。其中包括use strict
和use warnings
。这意味着使用my
声明变量。这可以捕获您遇到的许多编程错误。
我创建了一个名为%file_hash
的哈希。此哈希的关键是文件,其中的字段用冒号而不是空格分隔。这样,我不必担心两个文件之间的空间差异,因为字段的顺序是相同的。
此哈希的数据将是行本身。例如:
$file_hash{XYZ432345:Ethiopia:2567:89:ABC:P:28-Apr-14} =
"XYZ432345 Ethiopia 2567 89 ABC P 28-Apr-14 No Issue"
现在,如果我对第二个文件执行相同的操作,我可以看到%file_hash
中是否存在该密钥。如果确实如此,我知道我之前在文件#1中看过那条线,我将打印出这些数据。
通过使用哈希,我只需要遍历每个文件一次,而不是将每一行相互匹配。如果文件#1包含100行,而文件#2包含200行,那么我将经历300次迭代。按照你的方式,你循环100 * 200次,或2000次迭代。
use strict;
use warnings;
use autodie; # Will kill my program if file doens't open
use feature qw(say);
use constant {
file_1 => 'rep.txt',
file_2 => 'errep.txt',
};
#
# Open file #1 and build the hash index
#
open my $fh_1, '<', file_1;
my %file_hash;
while ( my $line = <$fh_1> ) {
chomp $line;
my $key = substr( $line, 0, 53);
$key =~ s/\s+/:/g;
$file_hash{$key} = $line;
}
close $fh_1;
#
# Open file #2 and compare the lines against that hash index
#
open my $fh_2, '<', file_2;
while ( my $line = <$fh_2> ) {
chomp $line;
my $key = $line;
$key =~ s/\s+/:/g;
if ( $file_hash{$key} ) {
say "$file_hash{$key};"
}
}
答案 2 :(得分:0)
我建议你使用这样的东西。请注意以下内容
use strict
和use warnings
,以及my
所有变量的声明
有意义的变量名称
词法文件句柄而不是全局句柄(my $rep_fh
而不是INFILE
)等。
我已将rep.txt
的内容复制到数组@rep
中,以便多次保存重新打开文件
我已将字段留在数组中,并使用List::Util
中的all
函数检查前六个字段是否匹配。如果您不单独使用它们,则无需将值复制到自己的标量变量中。
#!/usr/bin/perl
use strict;
use warnings;
use List::Util 'all';
open my $rep_fh, '<', 'rep.txt' or die qq{Unable to open "rep.txt" for input: $!};
my @rep = <$rep_fh>;
chomp @rep;
close $rep_fh;
open my $errep_fh, '<', 'errep.txt' or die qq{Unable to open "errep.txt" for input: $!};
while (my $errep_record = <$errep_fh>) {
chomp $errep_record;
my @errep_record = split /\t/, $errep_record;
for my $rep_record (@rep) {
my @rep_record = split /\t/, $rep_record;
if ( all { $rep_record[$_] eq $errep_record[$_] } 0 .. 5 ) {
print "$rep_record\n";
}
}
}