perl 正在获取给定路径下的目录名

xsuvu9jc  于 2023-02-16  发布在  Perl
关注(0)|答案(9)|浏览(112)

我正在尝试获取给定路径下所有一级目录的名称。
我尝试使用File::Find,但出现了问题。
有人能帮我吗?

vfh0ocws

vfh0ocws1#

使用-d文件检查运算符:

#!/usr/bin/perl

use strict;
use warnings;
use autodie;

my $path = $ARGV[0];
die "Please specify which directory to search" 
    unless -d $path;

opendir( my $DIR, $path );
while ( my $entry = readdir $DIR ) {
    next unless -d $path . '/' . $entry;
    next if $entry eq '.' or $entry eq '..';
    print "Found directory $entry\n";
}
closedir $DIR;
wgeznvg7

wgeznvg72#

如果不需要遍历整个目录层次结构,File::SlurpFile::Find更容易使用。

use strict;
use warnings;
use File::Slurp qw( read_dir );
use File::Spec::Functions qw( catfile );

my $path = shift @ARGV;
my @sub_dirs = grep { -d } map { catfile $path, $_ } read_dir $path;
print $_, "\n" for @sub_dirs;

如果您确实需要遍历层次结构,请查看CPAN以获得File::Find的更友好的替代方法。

最后,本着TIMTOWTDI的精神,这里有一些快速和肮脏的东西:

my @sub_dirs = grep {-d} glob("$ARGV[0]/*");
whlutmcx

whlutmcx3#

use File::Spec::Functions qw( catfile );

my ($path) = @ARGV;

opendir my $DIR, $path 
    or die "Cannot open directory: '$path': $!";

while ( my $entry = readdir $DIR ) {
    next if $entry =~ /\A\.\.?\z/;
    next unless -d catfile $path, $entry;
    print $entry, "\n";
}

closedir $DIR;

这对我很有效。

ekqde3dh

ekqde3dh4#

我在Windows XP下运行ActivePerl 5.10.1,如果我想获取根驱动器F下所有目录的名称,我将使用以下代码:

#!perl
opendir (DIR,'F:/');
my @folder = readdir(DIR);
foreach my $f (@folder)
{
   next if ($f =~ /\./);
   print "$f\n";
 }

嗯,这通常工作,因为我的文件夹名称不包含点。否则它失败。
好吧,看起来即使我的方法对我的情况有效,人们还是会因为它有错误而投反对票,所以我必须使用正式的方法,-d标志来检查一个文件是否是目录:
升级代码:

#!perl
use strict;
use warnings;

opendir (DIR, "F:/");
my @files = readdir(DIR);
my @dirs = grep { -d } @files;
print @dirs;
k10s72fa

k10s72fa6#

你可以使用find2perl把你的find命令翻译成perl。2更多信息请看perldocfind2perl。
maxdepth的解决方法:(参考自Randall)

$  find2perl /home/path -type d -eval 'my $slashes = $File::Find::name =~ tr#/##;return $File::Find::prune = 1 if $slashes > 2;return if $slashes ==2'

代码:

use strict;
    use File::Find ();
    use vars qw/*name *dir *prune/;
    *name   = *File::Find::name;
    *dir    = *File::Find::dir;
    *prune  = *File::Find::prune;
    sub wanted;

    File::Find::find({wanted => \&wanted}, '/');
    exit;
    sub wanted {
        eval { my $slashes = $File::Find::name =~ tr#/##;return $File::Find::prune = 1 if $slashes > 1;return if $slashes ==1 };
        if ( $? == "0" && -d _  ){
            print "$name --- \n";   
        }
    }

输出

$ pwd
/temp

$ tree
.
|-- dir1
|   |-- subdir1
|   |   |-- subsubdir1
|   |   `-- testsubdir1.txt
|   `-- testdir1.txt
|-- dir2
|   |-- subdir2
|   |   |-- subsubdir2
|   |   `-- testsubdir2.txt
|   `-- testdir2.txt
|-- dir3
|   `-- subdir3
|       `-- subsubdir3
`-- test

9 directories, 5 files

$ perl perl.pl
/temp ---
/temp/dir3 ---
/temp/dir1 ---
/temp/dir2 ---
uqzxnwby

uqzxnwby7#

使用文件::查找::规则

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

use Shell::Command qw( rm_rf touch mkpath );
use autodie;
use File::Find::Rule;

Main(@ARGV);
exit(0);

sub Main{
  use autodie;
  my $dir = "tmp";
  mkdir $dir;
#~   chdir $dir;
  mkpath "$dir/a/b/c/d";
  mkpath "$dir/as/b/c/d";
  mkpath "$dir/ar/b/c/d";

  print `tree`;
  print "---\n";
  print "$_\n"
    for File::Find::Rule->new->maxdepth(1)->directory->in($dir);

  print "---\n";

  print "$_\n"
    for grep -d, glob "$dir/*"; ## use forward slashes, See File::Glob

#~   chdir "..";
  rm_rf $dir;
}
__END__
.
|-- test.pl
`-- tmp
    |-- a
    |   `-- b
    |       `-- c
    |           `-- d
    |-- ar
    |   `-- b
    |       `-- c
    |           `-- d
    `-- as
        `-- b
            `-- c
                `-- d

13 directories, 1 file
---
tmp
tmp/a
tmp/ar
tmp/as
---
tmp/a
tmp/ar
tmp/as

或者使用文件::查找::规则前端查找规则

$ findrule tmp -maxdepth ( 1 ) -directory
tmp
tmp/a
tmp/ar
tmp/as
bgtovc5b

bgtovc5b8#

$path="/path/to/search";

 @files = `find $path -name myfile.name -type f`;
 print "@files\n";
lmvvr0a8

lmvvr0a89#

您可以使用File::Find进行查找。例如:

use File::Find ();

File::Find::find(\&wanted, '.');

sub wanted {
    if (-d) {    
        print "$File::Find::name\n";
    }
}

对于在'.'下找到的每个文件,这将调用wanted子例程。在子例程中,您可以使用-d来检查目录。
File::Find:find将下降到指定目录下的树中的所有子目录。

相关问题