views:

95

answers:

3

I want to know if there is anything that lets me do the following:

folder1 has files "readfile1" "f2" "fi5"

The only thing I know is that I need to read the file which starts with readfile, and I don't know what's there in the name after the string readfile. Also, I know that no other file in the directory starts with readfile.

How do I open this file with the open command?

Thank you.

+10  A: 

glob can be used to find a file matching a certain string:

my ($file) = glob 'readfile*';
open my $fh, '<', $file or die "can not open $file: $!";
toolic
Upvoted because of the simple solution and because of correct error handling.
David Harris
Well, to be complete, you should check for glob errors as well and if the return is null
drewk
Yea, he did the error handling right -- but will the OP? Advocating `autodie` is more honorable.
Evan Carroll
When assigning the first of a list, I prefer to do: `my $file = ( glob 'readfile*' )[0];` just to make the extraction from the list more explicit so some idiot doesn't come along and make my list assignment a scalar assignment and break things.
ysth
@Evan Carrol: Not fully. `glob 'readfile*` could return empty list, multiple files, or a directory. So, to be complete, these would need to be checked, no? Agreed on `autodie` though...
drewk
so long as the open () call fails, `autodie` will catch it.
Evan Carroll
+2  A: 

You can use glob for simple cases, as toolic suggests.

my ($file) = glob 'readfile*';

If the criteria for finding the correct file are more complex, just read the entire directory and use the full power of Perl to winnow the list down to what you need:

use strict;
use warnings;
use File::Slurp qw(read_dir);

my $dir   = shift @ARGV;
my @files = read_dir($dir);

# Filter the list as needed.
@files = map { ... } @files;
FM
+2  A: 

You don't necessarily need imports to read the contents of the directory - perl has some built-in functions that can do that:

opendir DIR, ".";
my ($file) = grep /readfile.*/, readdir(DIR);

open FILE, $file or die $!;
swilliams
Correct, but it is better to use lexical file handles and a 3 argument open. See http://stackoverflow.com/questions/1479741/why-is-three-argument-open-calls-with-lexical-filehandles-a-perl-best-practice
daotoad
Should be `/^readfile.*/` here.
Kinopiko