Difference Between Two Perl Command Line Forms

There are two forms of the Perl file name wildcard: <> and glob . But I found that there is a difference between the effect of these two forms:

I want to get all files with similar names using the 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 a difference: if $term is a string without spaces (or, say, one word), then (2) works well, but (1) does not work; if $term is a string with spaces (or, say, a few words), then (1) works well, (2) does not work.

Is there a difference between the two expressions? Thank you very much.

+2
source share
2 answers

<SomeStuff> equivalent to glob "SomeStuff" (except for all the ambiguities with <> , which are also used to read from file descriptors - see perldoc perlop and find I/O Operators there). Therefore, your examples are not equivalent. You have to use

 my @files = glob "\"rawdata/*_${term}_*.csv\""; #(2) 

instead.

However, why space in the template matters: perldoc -f glob tells a story. Regular glob (and therefore <> , which is implemented via glob ), treats spaces as a pattern delimiter. The documentation also mentions File::Glob and its bsd_glob function, which does not treat spaces as pattern delimiters. So think about it:

 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 that 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 
+4
source

The difference here is the use of quotation marks. From the docs:

Note that glob breaks its arguments into spaces and treats each segment as a separate template.

Using angle brackets <> does not require quotes. Glob requires quotes. Thus, the following equivalents:

 my @files = <rawdata/*_${term}_*.csv>; my @files = glob "rawdata/*_${term}_*.csv"; 

They will split the pattern if $ {term} contains a space. When you enter quotation marks on the <> form, this prevents this separation from spreading to $ {term} with spaces, thus looking for another pattern.

+4
source

All Articles