问题
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