【问题标题】:Using a Perl hash使用 Perl 哈希
【发布时间】:2012-01-06 17:34:56
【问题描述】:

这是我第一次在 Perl 中使用哈希,我遇到了一个奇怪的问题。我要做的是在目录中备份文件后,我使用 Perl 程序检查是否所有文件都出现在日志文件中。所以我有以下代码:

our (%missing_files) = (); # global definition on the top of the program

... do something ...

sub CheckTarResult {
  my (@dir_list)  = ();  # dir list
  my (@file_list) = ();  # will be filled with all file names in one dir
  my ($j) = "";
  my ($k) = "";          # loop variable
  my ($errors) = 0;      # number of missing files

  ... do something ...

  foreach $j (@dir_list) {

    @file_list = `ls $j`;

    foreach $k (@file_list) {
      $result = `cat $logfile | grep $k`;
      if ($result eq "") {
        $errors++;
        $missing_files{$j} = ${k};
      }
    }
    @file_list = ();
  }

    ... do something ...

  my($dir)  = "";
  my($file) = "";
  while ( ($dir, $file) = each(%missing_files) ) {
    print $dir . " : " . $file;
  }

我创建了一个空日志文件来进行测试,预期的结果应该是所有文件都丢失了,但不知何故,“missing_files”只将最后一个丢失的文件存储在每个目录中。逻辑似乎很简单,所以我在这里缺少什么?

编辑: 我使用了@Borodin 的建议,它奏效了。但是为了打印数组引用的内容,我们需要遍历数组中的元素。修改后的代码如下:

... everything before is the same ...
push @{$missing_files{$j}}, ${k};  # put elements in dictionary

# in the print statement
while( ($dir, $file) = each(%missing_files) ) {
  for $i ( 0 .. $#$file ) {   # $#$file represents the array size by reference
    print $dir . " : " . ${$file}[i];
  }
}

【问题讨论】:

  • 由于missing_files指的是一个哈希,你应该用$missing_files{$j}替换$missing_files[$j}
  • 这不会编译,因为你有 $missing_files[$j} = ${k}; - 你能把它改正吗?
  • Perl 将其称为哈希,而不是字典(已编辑)
  • 仅供参考,在 my 变量的声明中分配一个空列表是多余的。 my @array;my (@array);my (@array) = (); 都做同样的事情。创建一个没有元素的新变量@array
  • 一般来说,你应该让你的声明更接近它们的使用位置。与其在子程序的顶部声明循环变量,不如在循环中声明它们 foreach my $k (...) {...} 并且由于 @file_list 仅在循环内部使用,因此在分配给它时声明它 my @file_list = qx(ls $j) 它将超出范围在每次循环迭代结束时自行完成。

标签: perl hash


【解决方案1】:

Perl 哈希值只能包含一个标量。如果要存储事物列表,则必须将该标量设为数组引用。为此,请更改行

$missing_files{$j} = ${k};

push @{$missing_files{$j}}, ${k};

【讨论】:

  • 感谢您的回复,但如何打印参考?现在它只在我的打印语句中打印 ARRAY(0xd974bf0) (引用出现在 perl 中吗?)。
  • @dazhuangcao: 使用print "@{ $array_ref }"
  • print "$_\n" foreach @{$missing_files{$j}};
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
相关资源
最近更新 更多