使用perl检查嵌套目录结构是否为空

时间:2018-02-13 09:07:12

标签: perl perl-module

我的要求是检查嵌套目录结构是否包含任何二进制文件。





目录结构如下所示:

&# XA;

 <代码> DIR-A&#XA; |&#XA; | --dir-X&#XA; | |&#XA; | | --dir-X1&#XA; | | --dir-X2&#XA; |&#XA; | --dir-Y&#XA; | |&#XA; | | --dir-Y1&#XA; | | --dir-Y2&#XA; | | --dir-Y3&#XA; |&#XA; | --dir-Z&#XA; | |&#XA; | | --dir-Z1&#XA; | | --dir-Z2&#XA; | | --DIR-Z3&#xA;  
&#xA;&#xA;

在任何时间点,可以有更多目录在Level-1或Level-2,即可以有更多目录,即第1级的 DIR-P,DIR-Q 等,在第2级可以有 DIR-X3或DIR-Y4

&#xA;&#xA;

我编写了一个示例代码但如果找到 DIR-X1 就会退出。理想情况下,如果目录中有二进制文件,它应该退出。

&#xA;&#xA;
 #!/ usr / bin / perl&#xA;&#xA; my $ someDir =“/ path / of / DIR-A”;&#xA;我的@files =();&#xA;我的$文件;&#xA;我的$ i = 0;&#xA;&#xA; opendir(DIR,“$ someDir”)或死“Cant open $ someDir: $ \ N“;!&#XA; @files = readdir(DIR);&#xA; foreach $ file(@files)&#xA; {&#XA;除非($ file =〜/ ^ [。] [。]?\ z /)&#xA; {&#XA;打印“$ i:$ file \ n”; &#XA; $ I ++;&#XA;最后;&#XA; }&#XA; }&#XA;&#XA; if($ i!= 0)&#xA; {&#XA; print“目录包含文件!\ n”;&#xA; 1号出口; &#XA; &#xA;别的&#xA; {&#XA;打印“这个DIR-A是空的!\ n”;&#xA;退出0;&#xA; }&#xA;&#xA; closedir(DIR);&#xA;  
&#xA;&#xA;

请建议我按照以下方式获得预期的解决方案:

&#xA;&#xA;
 读取DIR-A&#xA;打印SUCCESS,如果没有嵌套目录有二进制文件。&#xA;打印错误,如果至少有一个嵌套目录有一个二进制文件。&#xA;  
&#xA;&#xA;

谢谢!

&#xA;

4 个答案:

答案 0 :(得分:2)

使用File::Find::Rule

#!/usr/bin/env perl
use strict;
use warnings;

use File::Find::Rule;

my $someDir = "/path/of/DIR-A";

my @files = File::Find::Rule->file()
                            ->name('*.bin')
                            ->in($someDir);

这将为您提供扩展名为&#39; .bin&#39;的所有文件。

如果您需要执行每个文件测试以检查它们是否为二进制文件&#39;然后,您可以在grep列表中使用@files

my @files = grep {-B} File::Find::Rule->file()
                                      ->in($someDir);

print "Binary files found\n" if @files;

此外:

  • use strict; use warnings;。这很好。
  • 代码格式化是一件非常好的事情。 perltidy -pbp让事情变得简单。

答案 1 :(得分:1)

我不清楚测试的二进制文件是什么。我假设在遍历的目录结构中找到的任何文件都是二进制文件。使用File::Find,这是一个核心模块:

use File::Find;

my $error = 0;
find(\&wanted, @ARGV);

if( $error ) {
  print "ERROR, $error files found\n";
}
else {
  print "SUCCESS\n";
}

sub wanted {
  if( -f $_ ) {
    $error++;
  }
}

您可以向wanted功能添加任何测试。 find函数将调用为也传递的目录列表中找到的每个文件提供的函数,该函数将以深度优先搜索顺序递归遍历(非常类似于find命令。)传递它@ARGV您可以根据需要使用目录列表调用脚本(可能使用像DIR-*这样的shell扩展。)

测试函数将获取$_中遍历的文件名,而当前工作目录设置为包含该文件的目录。

答案 2 :(得分:0)

您可以使用以下脚本来查找二进制文件是否存在递归。

#! /usr/bin/env perl
use warnings;
use strict;
use File::Find;

my $path="/path/of/DIR-A";

sub find_binary {
    my $file = $File::Find::name;

    if (-B $file && ! -d $file) {
        print "ERROR: At least one of the nested directories has a binary file : $file\n";
        exit;
    }
}

find(\&find_binary,$path);
print("SUCCESS: None of the nested directories have a binary file. \n");

答案 3 :(得分:0)

使用(警告:我的)模块File::Globstar

use v5.10;
use File::Globstar qw(globstar);

my $dir = $ARGV[0] // '.';
say join "\n", grep { -B && ! -d } globstar "$dir/**";

如果您想要列表中的文件列表,请指定它而不是打印它:

my @nondirs = grep { -B && ! -d } globstar "$dir/**";

如果你知道文件的扩展程序,你也可以这样做:

my @nondirs = grep { -B && ! -d } globstar "$dir/**/*.png";

请注意,文件测试-B会为空文件生成一个真值,这可能不是您想要的。在这种情况下,将测试更改为-B && -s && ! -d