【问题标题】:Perl: Determining whether an input is a file or directoryPerl:确定输入是文件还是目录
【发布时间】:2012-05-30 09:36:54
【问题描述】:

我目前正在编写一个程序,该程序最终将比较两个目录中的文件并显示每个文件中已更改的函数。但是,在检查目录中的内容是文件还是子目录时遇到了问题。现在,当我检查它是否只是带有 -d 检查的目录时,它不会捕获任何子目录。我在下面发布了我的部分代码。

opendir newDir, $newDir;
my @allNewFiles = grep { $_ ne '.' and $_ ne '..'} readdir newDir;
closedir newDir;

opendir oldDir, $oldDir;
my @allOldFiles = grep { $_ ne '.' and $_ ne '..'} readdir oldDir;
closedir oldDir;


foreach (@allNewFiles) {
    if(-d $_) {
        print "$_ is not a file and therefore is not able to be compared\n\n";
    } elsif((File::Compare::compare("$newDir/$_", "$oldDir/$_") == 1)) {
        print "$_ in new directory $newDirName differs from old directory $oldDirName\n\n";
        print OUTPUTFILE "File: $_ has been update. Please check marked functions for differences\n";
        print OUTPUTFILE "\n\n";
        print OUTPUTFILE "+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=\n\n";
    } elsif((File::Compare::compare("$newDir/$_", "$oldDir/$_") < 0)) {
        print "$_ found in new directory $newDirName but not in old directory $oldDirName\n";
        print "Entire file not printed to output file but instead only file name\n";
        print OUTPUTFILE "File: $_ is a new file!\n\n";
        print OUTPUTFILE "+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=\n\n";
    }
 }

foreach (@allOldFiles) {
    if((File::Compare::compare("$newDir/$_", "$oldDir/$_") < 0)) {
        print "$_ found in old directory $oldDirName but not in new directory $newDirName\n\n";
    }
 }

感谢您的帮助!

【问题讨论】:

  • 两件事:1. 裸词句柄不好(当然,你被告知这是因为你 use strict;use warnings;?),以及 2 . 为什么不直接在目录句柄的readdir 上做grep{-f $_}
  • 我确实使用 use stricts;并使用警告;当我尝试只使用 grep{-f $_} 时,它不会读取除 perl 文件之外的任何文件。
  • 然后开始。除非你正在做一个一次性的单行,否则你应该在你编写的每一位 Perl 代码中使用 use strict;use warnings;
  • 你为什么要自己做所有的工作而不是运行diff -rq $oldDir $newDir
  • 我不知道如何在 perl 中使用 diff,也找不到任何关于如何在线使用的文档。任何帮助将不胜感激。

标签: perl file compare subdirectory


【解决方案1】:

正如perldoc -f readdir 所说:

如果您打算对 readdir 中的返回值进行文件测试, 你最好把有问题的目录放在前面。否则,因为我们 那里没有 chdir,它会测试错误的文件。

if(-d "$newDir/$_") {

【讨论】:

    【解决方案2】:

    使用Path::Class

    use strict;
    use warnings;
    use Path::Class;
    
    
    my @allNewFiles = grep { !$_->is_dir } dir("/newDir")->children;
    

    【讨论】:

      【解决方案3】:

      使用递归调用先获取文件列表,然后对它们进行操作。

      my $filesA = {};
      my $filesB = {};
      
      # you are passing in a ref to filesA or B so no return is needed.
      sub getFiles {
        my ($dir, $fileList) = @_;
      
        foreach my $file (glob("*")) {
          if(-d $file) {
            getFiles($dir . "/" . $file, $fileList); # full relative path saved
          } else {
            $fileList{$dir . "/" . $file}++;         # only files are put into list
          }
        }
      }
      
      # get the files list
      my $filesA = getFiles($dirA);
      my $filesB = getFiles($dirB);
      
      # check them by using the keys from the 2 lists created.
      

      【讨论】:

        猜你喜欢
        • 2021-05-05
        • 1970-01-01
        • 2013-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-22
        • 2018-09-11
        • 1970-01-01
        相关资源
        最近更新 更多