Reputation: 77
i want to search for specific file inside a Folder but not in the subfolder of this folder. Following Structure is given:
FolderA
|
|__SubFolder1
|__File1.txt
|__File2.txt
|
|__File3.txt
|__File4.cmd
|__File5.txt
Now i am searching all txt files in Folder A like this:
sub GetFiles()
{
my @DIRS = (FolderA);
find ( \&searchFiles, @DIRS );
for my $myfile (%MYFILES) {
####do something with the files###
}
}
sub searchFiles()
{
return unless /\.txt/;
return unless -f $File::Find::name;
$MYFILES{$File::Find::name} = {'NAME'=> $File::Find::name }
}
The Code looks good to me but I always get all .txt Files, even those from Subfolder. Actual result is like this:
File1.txt File2.txt File3.txt File5.txt
But I want only
File3.txt File5.txt
Where did I the mistake?
Upvotes: 1
Views: 702
Reputation: 385657
You could use File::Find.
use File::Find qw( find );
my @dir_qfns = qw( FolderA );
find(
sub {
# Don't do anything for a base dir.
return if $_ eq '.';
# Don't recurse.
$File::Find::prune = 1;
stat($_)
or do {
warn("Skipping \"$_\": Can't stat: $!\n");
next;
};
-f _
or return;
/\.txt\z/
or return;
# ... do something with $File::Find::name/$_ ...
},
@dir_qfns,
);
It's far simpler with File::Find::Rule. (Isn't it always?)
use File::Find::Rule qw( );
my @dir_qfns = qw( FolderA );
for my $qfn (
File::Find::Rule
->mindepth(1)
->maxdepth(1)
->file
->name("*.txt")
->in(@dir_qfns)
) {
# ... do something with $qfn ...
}
You could also do it using glob
.
my @dir_qfns = qw( FolderA );
for my $dir_qfn (@dir_qfns) {
for my $fn (glob("\Q$dir_qfn\E/*.txt")) {
my $qfn = "$dir_qfn/$fn";
stat($qfn)
or do {
warn("Skipping \"$qfn\": Can't stat: $!\n");
next;
};
-f _
or next;
# ... do something with $fn/$qfn ...
}
}
(Note that using quotemeta
(e.g. via \Q..\E
as shown above) is not a proper way of generating a glob pattern from a directory name on Windows.)
Upvotes: 4
Reputation: 6798
Get list of all .dll
files in c:\Program Files\Windows Defender
directory
use strict;
use warnings;
use feature 'say';
my $dir_defend = 'c:\Program Files\Windows Defender';
my $files_dll = getFileList($dir_defend,'dll');
say '
File list
-------------------------';
say for @{ $files_dll };
sub getFileList {
my $dir = shift;
my $ext = shift;
opendir my $dh, $dir
or die "Can't opendir $dir";
my @files = grep { /\.${ext}$/ && -f "$dir/$_" } readdir($dh);
close $dh;
return \@files;
}
Output
File list
-------------------------
AMMonitoringProvider.dll
DefenderCSP.dll
EppManifest.dll
MpAsDesc.dll
MpAzSubmit.dll
MpClient.dll
MpCommu.dll
MpEvMsg.dll
MpOAV.dll
MpProvider.dll
MpRtp.dll
MpSvc.dll
MsMpCom.dll
MsMpLics.dll
MsMpRes.dll
ProtectionManagement.dll
shellext.dll
Upvotes: -1