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?

3
  • 1
    Isn't this question a duplicated of this one? stackoverflow.com/questions/1045792/… Commented Jan 27, 2010 at 18:35
  • 1
    @Leonardo Herrera Indeed, it is. Sorry, I did not remember that one. Voting to close. Commented Jan 27, 2010 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? Commented Feb 15, 2016 at 0:33

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This will not list hidden files (those starting with a dot) on GNU/Linux and probably other similar operating systems.
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
}

3 Comments

thanks! I'd use next if ($file =~ /^.+$/); though, to avoid the second statement ;) .
@ashraf regex has to be /^\.+$/ instead of /^.+$/
@Rauf yes I think you're right! :)
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.

1 Comment

and reead_dir removes . and .. for you, and if need be can prefix the directory into the filename

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.