Re: File::Find pattern match question
by Athanasius (Archbishop) on Oct 31, 2013 at 03:30 UTC
|
Hello RockE,
As you don’t actually ask a question, I’ll have to guess that you want a way to remove duplicate directories from your output. Here is one approach:
...
my %dirs;
find(\&dir_names, $wellpath);
print "$_\n" for sort keys %dirs;
sub dir_names
{
# skip over everything that is not a directory
return unless -d $File::Find::name;
# skip over directories that don't match required pattern
return unless $File::Find::dir =~ /[IPD]\d{8}$/;
$dirs{$File::Find::dir} = 1;
}
That is, instead of printing each directory as it is found, store it in a hash and print the hash keys after the call to find has completed. As hash keys are necessarily unique, no duplicates will be recorded.
Hope that helps,
Update: See the correction below.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Thanks for the reply :). Helps to ask a question...
I'd like the script to only report the directory name once, not print it again depending on how many sub directories it finds under the pattern matched directory.
I'll try your example - cheers.
We do have some duplicate directories so finding dupes is the next problem.
| [reply] [Watch: Dir/Any] |
|
$dirs{$File::Find::dir} = 1;
to
++$dirs{$File::Find::dir};
The code will run the same but now you'll have a count.
You can then find duplicates like this (untested):
my @dup_dirs = grep { $dirs{$_} > 1 } keys %dirs;
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
|
#!/usr/bin/perl
# dirpath
use strict;
use warnings;
use File::Find;
use Fcntl;
#*****************Path Variables**********************
our $wellpath = 'N:\\repos\\open\\Wells\\Regulated\\';
our $surveypath = 'N:\\repos\\open\\Surveys\\Regulated\\';
our $testpath = 'C:\\Temp\\';
#*******************************************************
my %dirs;
find(\&dir_names, $testpath);
print "$_\n" for sort keys %dirs;
sub dir_names
{
# skip over everything that is not a directory
return unless -d $File::Find::name;
# skip over directories that don't match required pattern
return unless $File::Find::dir =~ /[IPD]\d{8}$/;
$dirs{$File::Find::dir} = 1;
}
| [reply] [Watch: Dir/Any] [d/l] |
|
return unless $File::Find::dir =~ /[IPD]\d{8}$/;
is actually testing the parent directory, not the current file. Better to run both tests against the current filename in $_:
sub dir_names
{
return unless -d $_;
return unless $_ =~ /[IPD]\d{8}$/;
$dirs{$File::Find::name} = 1;
}
or just:
sub dir_names
{
return unless -d;
return unless /[IPD]\d{8}$/;
$dirs{$File::Find::name} = 1;
}
I think that fixes the problem.
Hope that helps,
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
How do I fix the code to only list the directory once.
Replace the period with a question mark (?) and you'll see he did have a question.
Idiot.
| [reply] [Watch: Dir/Any] |
|
How do I fix the code to only list the directory once. Replace the period with a question mark (?) and you'll see he did have a question. Idiot. You read all the replies and find the one which answered the question years ago
If you want somebody to point it out for you, don't be rude
| [reply] [Watch: Dir/Any] |
Re: File:Find pattern match question
by Anonymous Monk on Oct 31, 2013 at 07:27 UTC
|
#!/usr/bin/perl --
use strict; use warnings;
use File::Find::Rule qw/ find /;
my @dirs = find(
-directory ,
name => qr{([IPD]\d{8}$)},
-in => $wellpath,
);
print join "\n", @dirs, '';
| [reply] [Watch: Dir/Any] |
|
#!/usr/bin/perl
use strict;
use warnings;
use Fcntl;
#use File::Find;
#use File::Find::Rule;
use File::Find::Rule qw/ find /;
#*****************Path Variables*******************
our $wellpath = "N:\\repos\\open\\Wells\\Regulated";
our $surveypath = "N:\\repos\\open\\Surveys\\Regulated";
our $temp = "C:\\Temp\\";
#**************************************************
my @dirs = find(
-directory ,
name => qr{([MIPD]\d{8}$)},
-in => $temp,
);
print join "\n", @dirs, '';
C:\Temp\hddzip>perl dirpath3.pl
Can't locate method File::Find::Rule::-directory at dirpath3.pl line 16.
I have installed File::Find::Rule
| [reply] [Watch: Dir/Any] [d/l] |
|
:) Try "directory" instead of "-directory"
| [reply] [Watch: Dir/Any] |
Re: File:Find pattern match question
by Anonymous Monk on Oct 31, 2013 at 07:44 UTC
|
sub dir_names {
# Skip over everything that is not a directory. Note that
# chdir means we can use -X file tests on default $_.
-d or return;
# Skip over directories that don't match required pattern.
# Match against $_ instead of entire directory path.
/^[IPD]\d{8}$/ or return;
print "$File::Find::name\n";
# Do not recurse below current directory.
$File::Find::prune = 1;
}
| [reply] [Watch: Dir/Any] [d/l] [select] |