Question

I need to search for files in a directory that begin with a particular pattern, say "abc". I also need to eliminate all the files in the result that end with ".xh". I am not sure how to go about doing it in Perl.

I have something like this:

opendir(MYDIR, $newpath);
my @files = grep(/abc\*.*/,readdir(MYDIR)); # DOES NOT WORK

I also need to eliminate all files from result that end with ".xh"

Thanks, Bi

Was it helpful?

Solution

try

@files = grep {!/\.xh$/} <$MYDIR/abc*>;

where MYDIR is a string containing the path of your directory.

OTHER TIPS

opendir(MYDIR, $newpath); my @files = grep(/abc*.*/,readdir(MYDIR)); #DOES NOT WORK

You are confusing a regex pattern with a glob pattern.

#!/usr/bin/perl

use strict;
use warnings;

opendir my $dir_h, '.'
    or die "Cannot open directory: $!";

my @files = grep { /abc/ and not /\.xh$/ } readdir $dir_h;

closedir $dir_h;

print "$_\n" for @files;
opendir(MYDIR, $newpath) or die "$!";
my @files = grep{ !/\.xh$/ && /abc/ } readdir(MYDIR);
close MYDIR;
foreach (@files) { 
   do something
}

The point that kevinadc and Sinan Unur are using but not mentioning is that readdir() returns a list of all the entries in the directory when called in list context. You can then use any list operator on that. That's why you can use:

my @files = grep (/abc/ && !/\.xh$/), readdir MYDIR;

So:

readdir MYDIR

returns a list of all the files in MYDIR.

And:

grep (/abc/ && !/\.xh$/)

returns all the elements returned by readdir MYDIR that match the criteria there.

foreach $file (@files)
{
    my $fileN = $1 if $file =~ /([^\/]+)$/;

    if ($fileN =~ /\.xh$/)
    {
          unlink $file;
          next;
    }
    if ($fileN =~ /^abc/)
    {
          open(FILE, "<$file");
          while(<FILE>)
          {
             # read through file.
          }
    }
 }

also, all files in a directory can be accessed by doing:

$DIR = "/somedir/somepath";
foreach $file (<$DIR/*>)
{
  # apply file checks here like above.
}

ALternatively you can use the perl module File::find.

Instead of using opendir and filtering readdir (don't forget to closedir!), you could instead use glob:

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

my @files =
    grep !/^\.xh$/,                # filter out names ending in ".xh"
    map +(splitpath $_)[-1],       # filename only
    glob                           # perform shell-like glob expansion
        catfile $newpath, 'abc*';  # "$newpath/abc*" (or \ or :, depending on OS)

If you don't care about eliminating the $newpath prefixed to the results of glob, get rid of the the map+splitpath.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top