我是一个不成熟的Perl编码器,我在解决造成这个问题的原因时遇到了很多麻烦。似乎这是一个可变的问题。
sub patch_check {
my $pline;
my $sline;
while (<SYSTEMINFO>) {
chomp($_);
$sline = $_;
while (<PATCHLIST>) {
chomp($_);
$pline = $_;
print "sline $sline pline $pline underscoreline $_ "; #troubleshooting
print "$sline - $pline\n";
if ($pline =~ /($sline)/) {
#print " - match $pline -\n";
}
} #end while
}
}
代码更多,但我认为不相关。当我在第一个循环中打印$ sline时,它工作正常,但不在第二个循环中。我尝试将变量设为全局变量,但这也不起作用。
子表单的要点是我想打开一个文件(补丁)并查看它是否在(systeminfo)中。我也尝试将文件读入数组并进行foreach循环。
有没有人有其他解决方案?
答案 0 :(得分:4)
看起来你的实际目标是找到两个文件中的行,对吗?正常(并且效率更高! - 它只需要你在每个文件中读取一次,而不是在另一个文件中读取每一行的所有文件)在Perl中执行此操作的方法是从一个文件中读取行哈希,然后在另一个文件的每一行上使用哈希查找来检查匹配。
未经测试(但应该工作的那么简单)代码:
sub patch_check {
my %slines;
while (<SYSTEMINFO>) {
# Since we'll just be comparing one file's lines
# against the other file's lines, there's no real
# reason to chomp() them
$slines{$_}++;
}
# %slines now has all lines from SYSTEMINFO as its
# keys and the values are the number of times the
# line appears, in case that's interesting to you
while (<PATCHLIST>) {
print "match: $_" if exists $slines{$_};
}
}
顺便说一句,如果您正在从SYSTEMINFO
和PATCHLIST
阅读数据,那么您就是以老式的方式进行的。如果您有机会,请阅读lexical filehandles and the three-argument form of open
,如果您还不熟悉它们的话。
答案 1 :(得分:3)
您的代码没有进入PATCHLIST而第二次循环通过SYSTEMINFO while循环,因为您已经第一次读取了PATCHLIST的所有内容。您必须重新打开PATCHLIST文件句柄才能完成您要执行的操作。
这是一种非常低效的方法,可以查看一个文件的行是否与另一个文件的行匹配。用另一种方式看看带有-f标志的grep。
grep -f PATCHFILE SYSTEMINFO
答案 2 :(得分:2)
在这种情况下我喜欢做的是:读取一个文件并根据您要查找的值创建哈希键。然后读取第二个文件,看看密钥是否已经存在。这样,您只需要读取一次文件。
以下是未经测试的示例代码:
sub patch_check {
my %patches = ();
open(my $PatchList, '<', "patch.txt") or die $!;
open(my $SystemInfo, '<', "SystemInfo.txt") or die $!;
while ( my $PatchRow = <$PatchList> ) {
$patches($PatchRow) = 0;
}
while ( my $SystemRow = <$SystemInfo> ) {
if exists $patches{$SystemRow} {
#The Patch is in System Info
#Do whateever you want
}
}
}
答案 3 :(得分:-1)
您无法在另一个文件的读取循环中读取一个文件。将一个文件拖入,然后将一个循环作为slurped文件的foreach行,外部循环,读取循环。