【问题标题】:Perl: opendir, while readdir, next if, hashPerl: opendir, while readdir, next if, hash
【发布时间】:2015-06-06 17:15:21
【问题描述】:

我有一个目录$tmp,其中包含名称语法为.X*-lock 的文件以及其他普通文件和目录。

我将$tmp 的内容与对应于不应删除的.X*-lock 文件名的哈希表中的值进行比较。然后,我希望脚本删除任何且仅删除不在哈希表中的 .X*-lock 文件。它不能删除普通文件(非“.”文件)、目录或. & ..

这里有一些代码:

 my %h = map { $_ => 1 } @locked_ports;
 #open /tmp and find the .X*-lock files that DO NOT match locked_ports (NOT WORKING)

opendir (DIR, $tmp ) or die "Error in opening dir $tmp\n";
    while ( (my $files = readdir(DIR)))
    {
      next if((-f $files) and (-d $files));
      next if exists $h{$files};
      #unlink($files) if !-d $files;
        if (! -d $files){print "$files\n"};
     }
      closedir(DIR);

如您所见,现在我将 unlink 替换为 print,因此我知道列出了正确的文件。

假设在我的$tmp 目录中,我有以下文件和目录:

./
../
cheese
.X0-lock
.X10-lock
.X11-unix/
.X1-lock
.X2-lock
.X3-lock
.X4-lock
.X5-lock

但只有.X1-lock 在哈希表中。因此我想打印/删除所有其他.X*-lock 文件,但不是.X11-unix/ 目录、cheese 文件或...

使用上面的代码,它不会打印...,这很好,但它会打印cheese.X11-unix。我怎样才能改变它,这样它们就不会被打印出来?

(注意:这是Perl: foreach line, split, modify the string, set to array. Opendir, next if files=modified string. Unlink files 的一个词干,我被告知不要再在 cmets 中提问,所以我提出了一个新问题。)

谢谢!

【问题讨论】:

  • 我不认为这是您描述的问题,但请记住,readdir 不会返回文件的路径,只是返回文件名。除非您的当前目录位于 $tmp 中,否则您必须自己添加路径(此处为 $tmp),例如 next if -d "$tmp/$files"
  • @JimDavis 将next if((-f $files) and (-d $files)); 行更改为next if(-d "$tmp/$files"); 确实消除了输出中的.X11-unix/。现在我只需要让它忽略所有文件,除了名称语法为.X*-lock 的文件,因为cheese 仍然出现。更近了!谢谢:)

标签: perl unix hash


【解决方案1】:

我可能会这样做:

opendir (my $dirhandle, $tmp) or die "Error in opening dir $tmp: $!";
while (my $file = readdir($dirhandle)) {
    # skip directories and files in our hash
    next if -d "$tmp/$file" || $h{$file};
    # skip files that don't look like .X###-lock
    next unless $file =~ /
        \A    # beginning of string
        \.    # a literal '.'
        X     # a literal 'X'
        \d+   # 1 or more numeric digits
        -lock # literal string '-lock'
        \z    # the end of the string
    /x; # 'x' allows free whitespace and comments in regex
#   unlink("$tmp/$file");
    print "$file\n"
}
closedir($dirhandle);

如果你觉得它更具可读性,最后一个条件可以写成:

next if $file !~ /\A\.X\d+-lock\z/;

甚至:

    if ($file =~ /\A\.X\d+-lock\z/) {
    #   unlink("$tmp/$file");
        print "$file\n"
    }

【讨论】:

  • 行得通!你有什么地方可以让我更好地理解/\A\.X\d+-lock\z/;吗?谢谢
  • perldoc perlre,但我会编辑答案以更好地记录它。
猜你喜欢
  • 2011-05-15
  • 2016-06-21
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-12
  • 2021-05-16
  • 1970-01-01
相关资源
最近更新 更多