使用 perl 检查嵌套目录结构是否为空
Check if the nested directory structure is empty using perl
我的要求是检查嵌套目录结构是否包含任何二进制文件。
目录结构如下所示:
DIR-A
|
|--DIR-X
| |
| |--DIR-X1
| |--DIR-X2
|
|--DIR-Y
| |
| |--DIR-Y1
| |--DIR-Y2
| |--DIR-Y3
|
|--DIR-Z
| |
| |--DIR-Z1
| |--DIR-Z2
| |--DIR-Z3
在任何时间点,Level-1 或 Level-2 都可以有更多目录,即在 level-1 可以有更多目录,即 DIR-P, DIR-Q
等,并且可以有 DIR-X3 or DIR-Y4
在 2 级。
我写了一个示例代码,但是如果它找到 DIR-X1
,它就会退出,理想情况下,如果目录中有一个二进制文件,它应该退出。
#!/usr/bin/perl
my $someDir = "/path/of/DIR-A";
my @files = ();
my $file;
my $i=0;
opendir(DIR, "$someDir") or die "Cant open $someDir: $!\n";
@files = readdir(DIR);
foreach $file(@files)
{
unless ($file =~ /^[.][.]?\z/)
{
print "$i : $file \n";
$i++;
last;
}
}
if ($i != 0)
{
print "The directory contains files! \n";
exit 1;
}
else
{
print "This DIR-A is Empty! \n";
exit 0;
}
closedir(DIR);
请建议我获得如下预期的解决方案:
read DIR-A
print SUCCESS, if none of the nested directories have a binary file.
print ERROR, if at least one of the nested directories has a binary file.
谢谢!
#!/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);
这将为您提供扩展名为“.bin”的所有文件。
如果您需要执行每个文件测试以检查它们是否 'binary',那么您可以在 @files
列表中使用 grep
。
my @files = grep {-B} File::Find::Rule->file()
->in($someDir);
print "Binary files found\n" if @files;
另外:
use strict;
use warnings;
。不错。
- 代码格式化真是个好东西。
perltidy -pbp
让一切变得简单。
您可以使用以下脚本递归地查找二进制文件是否存在。
#! /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");
使用(警告:我的)模块 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
.
我不清楚你的测试用的是什么二进制文件。我假设在遍历的目录结构中找到的任何文件都是二进制文件。使用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
您可以根据需要使用目录列表调用脚本(可能使用 shell 扩展,如 DIR-*
。)
测试函数会在$_
中获取正在遍历的文件名,而当前工作目录设置为包含该文件的目录。
我的要求是检查嵌套目录结构是否包含任何二进制文件。
目录结构如下所示:
DIR-A
|
|--DIR-X
| |
| |--DIR-X1
| |--DIR-X2
|
|--DIR-Y
| |
| |--DIR-Y1
| |--DIR-Y2
| |--DIR-Y3
|
|--DIR-Z
| |
| |--DIR-Z1
| |--DIR-Z2
| |--DIR-Z3
在任何时间点,Level-1 或 Level-2 都可以有更多目录,即在 level-1 可以有更多目录,即 DIR-P, DIR-Q
等,并且可以有 DIR-X3 or DIR-Y4
在 2 级。
我写了一个示例代码,但是如果它找到 DIR-X1
,它就会退出,理想情况下,如果目录中有一个二进制文件,它应该退出。
#!/usr/bin/perl
my $someDir = "/path/of/DIR-A";
my @files = ();
my $file;
my $i=0;
opendir(DIR, "$someDir") or die "Cant open $someDir: $!\n";
@files = readdir(DIR);
foreach $file(@files)
{
unless ($file =~ /^[.][.]?\z/)
{
print "$i : $file \n";
$i++;
last;
}
}
if ($i != 0)
{
print "The directory contains files! \n";
exit 1;
}
else
{
print "This DIR-A is Empty! \n";
exit 0;
}
closedir(DIR);
请建议我获得如下预期的解决方案:
read DIR-A
print SUCCESS, if none of the nested directories have a binary file.
print ERROR, if at least one of the nested directories has a binary file.
谢谢!
#!/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);
这将为您提供扩展名为“.bin”的所有文件。
如果您需要执行每个文件测试以检查它们是否 'binary',那么您可以在 @files
列表中使用 grep
。
my @files = grep {-B} File::Find::Rule->file()
->in($someDir);
print "Binary files found\n" if @files;
另外:
use strict;
use warnings;
。不错。- 代码格式化真是个好东西。
perltidy -pbp
让一切变得简单。
您可以使用以下脚本递归地查找二进制文件是否存在。
#! /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");
使用(警告:我的)模块 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
.
我不清楚你的测试用的是什么二进制文件。我假设在遍历的目录结构中找到的任何文件都是二进制文件。使用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
您可以根据需要使用目录列表调用脚本(可能使用 shell 扩展,如 DIR-*
。)
测试函数会在$_
中获取正在遍历的文件名,而当前工作目录设置为包含该文件的目录。