Reputation: 39
I have a simple perl code that displays the names of the files in a given directory
opendir my $dir, "./images/sampleImages" or die "Cannot open directory: $!";
my @Images = grep {!/^\./} readdir $dir;
closedir $dir;
I have added a regex statement to remove all single and double dots, since readdir adds them as special characters and this is working perfectly fine. However I want only the files with the extensions of .jpg/.jpeg/.png/.gif to be read. I have found a regex that does that, which is :
(/\.(gif|jpg|jpeg|png)$/i)
But I can't seem to make them work together. I have tried everything I could find on the subject here, combining the statements in different ways but either they give errors, or flat out do not work the way it should. Any help would be greatly appreciated, thanks in advance!
Upvotes: 0
Views: 81
Reputation: 6798
Following code filters in only images, no need to look at .
and ..
at all
use strict;
use warnings;
use feature 'say';
my $dirname = './images/sampleImages';
opendir my $dir, $dirname
or die "Cannot open directory: $dirname";
my @Images = grep { /\.(gif|jpg|jpeg|png)$/i } readdir $dir;
closedir $dir;
map{ say } @Images;
Upvotes: 0
Reputation: 132773
You can use multiple match operators:
my @dirs =
grep { /\.(?:gif|jpe?g|png)\z/i && ! /\A\./ }
readdir $dir;
I typically make one grep
per idea so I can disable them individually:
my @dirs =
grep { /\.(?:gif|jpe?g|png)\z/i }
grep { ! /\A\./ }
readdir $dir;
And often I add in a map
to make the full path since readdir
doesn't do that for you (and usually I do it wrong first then come back to do this):
my @dirs =
map { catfile( $dir, $_ ) }
grep { /\.(?:gif|jpe?g|png)\z/ }
grep { ! /\A\./ }
readdir $dir;
And, readdir
doesn't "add" .
and ..
. Those are the virtual directories that mean the current directory and the parent directory. If those are the only things that you want to remove, then you can improve that part to match only those rather than all hidden files:
my @dirs =
map { catfile( $dir, $_ ) }
grep { /\.(?:gif|jpe?g|png)\z/ }
grep { ! /\A\.\.?\z/ }
readdir $dir;
Again, even though I know that and written that a million times, I still only add it once I see .
and ..
in the output. Some things never change.
Upvotes: 3
Reputation: 3705
Does this work?
my @Images = grep { !/^\./ && /\.(gif|jpg|jpeg|png)$/i } readdir $dir;
Upvotes: 5