嵌套while循环似乎没有保持变量适当

时间:2011-04-10 22:53:19

标签: perl variables while-loop scope

我是一个不成熟的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循环。

有没有人有其他解决方案?

4 个答案:

答案 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{$_};
  }
}

顺便说一句,如果您正在从SYSTEMINFOPATCHLIST阅读数据,那么您就是以老式的方式进行的。如果您有机会,请阅读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行,外部循环,读取循环。