29

Possible Duplicate:
How can I list all of the files in a directory with Perl?

I want to loop through a few hundred files that are all contained in the same directory. How would I do this in Perl?

Community
  • 1
  • 1
adhanlon
  • 6,407
  • 13
  • 43
  • 41
  • 1
    Isn't this question a duplicated of this one? http://stackoverflow.com/questions/1045792/how-can-i-list-all-of-the-files-in-a-directory-with-perl – Leonardo Herrera Jan 27 '10 at 18:35
  • 1
    @Leonardo Herrera Indeed, it is. Sorry, I did not remember that one. Voting to close. – Sinan Ünür Jan 27 '10 at 18:36
  • I don't see how this is a duplicate. The question asks how to loop through files in a directory. The marked 'duplicate' asks how to list all the files in a directory. Clearly different. Why mark as a duplicate? – CJ7 Feb 15 '16 at 00:33

3 Answers3

53
#!/usr/bin/perl -w

my @files = <*>;
foreach my $file (@files) {
  print $file . "\n";
}

Where

 @files = <*>;

can be

 @files = </var/www/htdocs/*>;
 @files = </var/www/htdocs/*.html>;

etc.

Sam B
  • 27,273
  • 15
  • 84
  • 121
EToreo
  • 2,936
  • 4
  • 30
  • 36
  • This will not list hidden files (those starting with a dot) on GNU/Linux and probably other similar operating systems. – josch Dec 22 '16 at 16:07
23

Enjoy.

opendir(DH, "directory");
my @files = readdir(DH);
closedir(DH);

foreach my $file (@files)
{
    # skip . and ..
    next if($file =~ /^\.$/);
    next if($file =~ /^\.\.$/);

    # $file is the file used on this iteration of the loop
}
Community
  • 1
  • 1
skarface
  • 910
  • 6
  • 19
13

You can use readdir or glob.

Or, you can use a module such as Path::Class:

Ordinarily children() will not include the self and parent entries . and .. (or their equivalents on non-Unix systems), because that's like I'm-my-own-grandpa business. If you do want all directory entries including these special ones, pass a true value for the all parameter:

@c = $dir->children(); # Just the children
@c = $dir->children(all => 1); # All entries

In addition, there's a no_hidden parameter that will exclude all normally "hidden" entries - on Unix this means excluding all entries that begin with a dot (.):

@c = $dir->children(no_hidden => 1); # Just normally-visible entries

Or, Path::Tiny:

@paths = path("/tmp")->children;
@paths = path("/tmp")->children( qr/\.txt$/ );

Returns a list of Path::Tiny objects for all files and directories within a directory. Excludes "." and ".." automatically.

If an optional qr// argument is provided, it only returns objects for child names that match the given regular expression. Only the base name is used for matching:

@paths = path("/tmp")->children( qr/^foo/ );
# matches children like the glob foo*

Getting the list of directory entries into an array wastes some memory (as opposed to getting one file name at a time), but with only a few hundred files, this is unlikely to be an issue.

Path::Class is portable to operating systems other than *nix and Windows. On the other hand, AFAIK, its instances use more memory than do Path::Tiny instances.

If memory is an issue, you are better off using readdir in a while loop.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339