Hello,

 I am trying to write a Perl script that searches through a directory on Windows and returns the file names matching a pattern that's stored in a scalar variable. Please find my code below:



use warnings;
use strict;
use Data::Dumper;
use MIME::Lite;
my @fields;
my @files;
my $dir="places";

sub _processfile()
{
    my %places=();
    open(FH,"<","ms.csv") or die "Can't open file: $!\n";
    opendir(my $dh, $dir) or die "Can't open dir: $!\n";
    while(my $line = <FH>)
    {
        chomp($line);
        @fields = split(/\,/,$line);
        $places{$fields[0]}=$fields[1];
    }
    closedir $dh;
    close(FH);
}

_processfile();

The file contains the names of buildings and the second column contains information about that building. I want to read through the file, grab the building name and search a directory for files that contain the building name. All the files are of PDF format and contain the name of the building within the name.

Data example:

Building1,Data1;Data2
Building2,Data3;Data4

I have tried to use grep to make this happen, but it doesn't work when the pattern in a variable. If I use an explicit pattern rather than a variable, it returns correctly. Please assist!

Thanks!

Hi magikman,

Going through your post, I think you are either asking two different questions or the first question is a sub-set of the second one.

The first question on it own as stated:

I am trying to write a Perl script that searches through a directory on Windows and returns the file names matching a pattern that's stored in a scalar variable

can simply be done like so:

use warnings;
use strict;

my $search = qr/\.pdf/;

print join $/ => grep { /$search$/ } glob("*.*");

In other words, using glob get all the files in current directory and use grep to check the ones that matched your search string.

However, on your other question, you can simply get all the files in the current directory like above into an array variable.
Then open file using a lexical scoped filehandle, get all the filename in the file into an hash. Afterwards, using a for loop, checking through the array variable which contain the names of files in the directory check in the hash the names that existed and print them out.

Somewhat like thus:

use warnings;
use strict;

my @file_names = glob("*.*");
my %doc_name;

open my $fh, '<', "naming.txt" or die "can't find file: $!";
$doc_name{ (split)[8] } = 1 while <$fh>;
close $fh or die "can't close file: $!";

for my $file (@file_names) {
    print $file, $/ if $doc_name{$file};
    next;
}

Please note that though the example above worked using output from the command ls -l in a linux OS as the file which contain names of files to look for in a current directory. I only show how this could be done, since the OP didn't post any dataset for demonstration.

Lastly, there are several other things, I observed in your post that time will not permit me to shed more light on. Like you opened a directory handler but was not use. Like it is better to use a module for some stuff like working on CSV file. You could use Text::CSV:XS or Text::CSV. Of course, one could say your file might be a simple CSV file.

Edited 2 Years Ago by 2teez

In case, you notice that the demonstrated codes above print back what was rightly in the hash, then you got the point.

All you needed to do to make it solve explicitly is to combine the first solution provided with the second one (i.e making the first solution replace the for loop in the second solution)

Hope this helps.

This article has been dead for over six months. Start a new discussion instead.