Re: Pulling a file with a given extension
by Roy Johnson (Monsignor) on Oct 18, 2005 at 16:48 UTC
|
That's what file globs are for.
my $datfile = (glob '*.dat')[0];
Caution: Contents may have been coded under pressure.
| [reply] [d/l] |
|
|
Be aware though that a glob might be slower than a loop:
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw( cmpthese );
sub globber {
return(( glob '*.xml')[0]);
}
sub opener {
opendir my $dir, '.';
my $file;
while (defined($file= readdir $dir)) {
last if $file=~ /\.xml$/;
}
closedir $dir;
return $file;
}
cmpthese(5000, {
globber => \&globber,
opener => \&opener,
});
Rate globber opener
globber 654/s -- -76%
opener 2688/s 311% --
s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
+.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
| [reply] [d/l] [select] |
|
|
That all depends ... on whether you manage to get the opener to work ;-)
I'd rather go with a slow function that was fast to write than a fast function that was slow and error prone to write. I can always speed up working code (or, failing that, fall back to the original slow code) much easier than taking fast code and making it work ;-)
(Note - this is in no way intended to say that the above code doesn't work, only that I've seen many people get fooled when trying to use the *dir functions - including myself.)
| [reply] |
|
|
| [reply] |
|
|
It makes for a very interesting study in the pathology of "programmer's self-delusion", trying to reconcile this remark ("I'd forgottern that my code was moved to a different drive..."), with the remark you made about 80 minutes earlier: Yes, I added a print statement that verified I'm getting into the correct directory, and yes, the directory has "test.dat" in it.
We all do it -- some more than others, perhaps, but no one is immune. The trick is to remember this fact, to recognize when it strikes, and to work out some ploy to circumvent the personal defect... like "Hmm, if someone else besides me were looking at this, what would they ask/look for/test..."
| [reply] |
Re: Pulling a file with a given extension
by nimdokk (Vicar) on Oct 18, 2005 at 15:51 UTC
|
I just ran your code and it worked for me except I added an "opendir" as well:
opendir DIR, '.' or die "Cannot open current dir. $!";
my @files = grep { /\.(?:dat)$/i } readdir DIR;
closedir DIR;
my $datfile = $files[0];
print "\$datfile ==> $datfile\n";
| [reply] [d/l] |
Re: Pulling a file with a given extension
by ikegami (Patriarch) on Oct 18, 2005 at 15:51 UTC
|
Did you check whether DIR was opened successfully? If you're using a relative directory, are you sure you know the current directory? | [reply] |
|
|
| [reply] |
|
|
Do you see "test.dat" outputted when you do
opendir DIR, '.' or die "Cannot open current dir. $!";
print("$_\n") foreach readdir DIR;
closedir DIR;
If so, I suspect the filename isn't actually "test.dat". Maybe it has a trailing space. Maybe there's some funky character in there that's not getting displayed. | [reply] [d/l] |
Re: Pulling a file with a given extension
by amw1 (Friar) on Oct 18, 2005 at 16:09 UTC
|
To do this recursively. . .
find2perl /some/dir -name "*.dat"
#! /usr/bin/perl -w
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if 0; #$running_under_some_shell
use strict;
use File::Find ();
# Set the variable $File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.
# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name = *File::Find::name;
*dir = *File::Find::dir;
*prune = *File::Find::prune;
sub wanted;
# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, '/some/dir');
exit;
sub wanted {
/^.*\.dat\z/s
&& print("$name\n");
}
Put your processing code into wanted. | [reply] [d/l] |
Re: Pulling a file with a given extension
by cognizant (Pilgrim) on Oct 19, 2005 at 03:46 UTC
|
If you want to check the filename inside subdirectory too, then you can use the following code.
$input = $ARGV[0]; #input directory
find(sub {push(@ara, $File::Find::name) if -d}, $input);
foreach $arr (@ara)
{
opendir (FIN, "$arr") || die("can't open $arr");
my @cnt = readdir(FIN);
chdir($arr);
foreach $temp (@cnt)
{
print "$temp" if ($temp=~/\.dat$/);
}
}
Cheers
--C
| [reply] [d/l] |