开发者

How to check in Perl whether there is any sub folder exist in a folder?

开发者_开发问答

Is there a way to check whether there is any subfolder exist inside a folder. I would like to do this in Perl?


Glob through the contents of the directory, and check whether it is a directory with -d.

sub has_subfolder {
  my $directory = shift;
  for ( <$directory/*>, <$directory/.*> ) {
    next if m@/\.\.?$@; # skip . and ..
    return 1 if -d;
  }
  return 0;
}


if (grep -d, glob("$folder/*")) {
    print "$folder has subfolder(s)\n";
}  

If you want to deal with directories matching .*, you could do:

if (grep -d && !/\.\.?$/, glob("$folder/.* $folder/*")) {
    print "$folder has subfolder(s)\n";
}  


You can use the'File::Find' module for this purpose. File::Find processes and scans a directory recursively. Here is the sample code:

use File::Find;
my $DirName = 'dirname' ;

sub has_subdir 
{
    #The path of the file/dir being visited.
    my $subdir = $File::Find::name;

    #Ignore if this is a file.
    return unless -d $subdir;

    #Ignore if $subdir is $Dirname itself.
    return if ( $subdir eq $DirName);

    # if we have reached here, this is a subdirector.
    print "Sub directory found - $subdir\n";
}

#For each file and sub directory in $Dirname, 'find' calls 
#the 'has_subdir' subroutine recursively.
find (\&has_subdir, $DirName);


In order to check if a subfolder exists in a directory (without knowing any names):

my $dir_name = "some_directory";
opendir my $dir, $dir_name
    or die "Could not open directory $dir_name: $!";

my $has_subfolder = grep { -d && !/(^|\/)\.\.?$/ } map { ("$dir_name"||'.')."/$_" } readdir $dir;

In other words, it checks for one or more files in the directory which are themselves directories.

If you want a specific subfolder, just use Geo's answer.

Edit: This is getting silly now, but here's a truly general-purpose answer. :-P Someone else is getting the check mark anyway.


sub hasSubDir {
    my $dir_name = shift;
    opendir my $dir, $dir_name
      or die "Could not open directory $dir_name: $!";
    my @files = readdir($dir);
    closedir($dir);
    for my $file (@files) {
       if($file !~ /\.\.?$/) {
           return 1 if -d $dir/$file;
       }
    }
    return 0;
}


OK, I'm just gonna have to submit my own answer

sub has_subfolder {
  my $dir = shift;
  my $found = 0;
  opendir my $dh, $dir or die "Could not open directory $dir: $!";
  while (my $_ = readdir($dh)) {
    next if (/^\.\.?$/);        # skip '.' and '..'
    my $path = $dir . '/' . $_; # readdir doesn't return the whole path
    if (-d $path) {             # found a dir?  record it, and leave the loop!   
      $found = 1;
      last;    
  }
  closedir($dh);                # make sure we cleanup after!
  return $found;
}

Compared to other answers:

  • finds hidden directories
  • completes as soon as it finds a match
  • doesn't traverse the tree twice (once for normal files, and again for hidden files)

EDIT - I see the requirements just changed (sigh). Fortunately the code above is trivially modified:

sub get_folders {
  my $dir = shift;
  my @found;
  opendir my $dh, $dir or die "Could not open directory $dir: $!";
  while (my $_ = readdir($dh)) {
    next if (/^\.\.?$/);           # skip '.' and '..'
    my $path = $dir . '/' . $_;    # readdir doesn't return the whole path
    push(@found, $_) if (-d $path) # found a dir? record it 
  }
  closedir($dh);                   # make sure we cleanup after!
  return @found;
}


if(-e "some_folder/some_subfolder") {
   print "folder exists";
}
else {
   print "folder does not exist";
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜