问题
There are two forms of Perl filename wildcard command: <>
and glob
. But I found there is difference between the effect of these two forms:
I want to retrieve all the files with similar names, using following code:
my @files = <"rawdata/*_${term}_*.csv">; #(1)
and another format:
my @files = glob "rawdata/*_${term}_*.csv"; #(2)
I expect to get the same result using these two codes. But there is difference: if the $term
is a string without spaces (or to say, one word), then (2) works well, but (1) doesn't work; if the $term
is a string with spaces (or to say, several words), then (1) works well, (2) doesn't work.
Is there any difference between these two expressions? Thanks a lot.
回答1:
<SomeStuff>
is equivalent to glob "SomeStuff"
(apart from all the ambiguities with <>
also being used for reading from file handles -- see perldoc perlop
and look for I/O Operators
there). Therefore your examples aren't equivalent. You should use
my @files = glob "\"rawdata/*_${term}_*.csv\""; #(2)
instead.
However, as to why space in the pattern makes a difference: perldoc -f glob
tells the story. The normal glob
(and therefore <>
which is implemented via glob
) treat whitespace as a pattern separator. The documentation also mentions File::Glob
and its function bsd_glob
which does not treat spaces as pattern separators. Therefore consider using this instead:
use File::Glob ':glob';
my $term1 = "some stuff";
my @files1 = glob "dir/${term1}*";
my $term2 = "more";
my @files2 = glob "dir/${term2}*";
print join(' :: ', sort @files1), "\n", join(' :: ', sort @files2), "\n";
Possible output with some files I just created:
[0 mosu@tionne ~/tmp] ~/test/test1.pl
dir/some stuff is betther than other stuff.doc :: dir/some stuffy teachers.txt
dir/more beer.txt :: dir/more_is_less.csv
回答2:
The difference here lies in the use of quotes. From the docs:
Note that glob splits its arguments on whitespace and treats each segment as separate pattern.
Using angled brackets <> does not require quotes. Glob requires quotes. As such, the following are equivalent:
my @files = <rawdata/*_${term}_*.csv>;
my @files = glob "rawdata/*_${term}_*.csv";
They will both split the pattern if ${term} contains a space. When you introduce quotes to the <> form, it prevents this split from happening on ${term}'s with spaces, thus searching for a different pattern.
来源:https://stackoverflow.com/questions/12115772/difference-between-two-forms-of-perl-filename-wildcard-command