2

Perl 文件名通配符命令有两种形式:<>glob. 但是我发现这两种形式的效果是有区别的:

我想使用以下代码检索具有相似名称的所有文件:

my @files = <"rawdata/*_${term}_*.csv">;   #(1)

和另一种格式:

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

我希望使用这两个代码得到相同的结果。但是有区别:如果$term是一个没有空格的字符串(或者说,一个单词),那么(2)可以正常工作,但是(1)不行;如果$term是一个带空格的字符串(或者说是几个单词),那么(1)效果很好,(2)不起作用。

这两种表达方式有区别吗?非常感谢。

4

2 回答 2

4

这里的区别在于引号的使用。从文档:

请注意,glob 在空格上拆分其参数并将每个段视为单独的模式。

使用尖括号 <> 不需要引号。Glob 需要引号。因此,以下是等价的:

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

如果 ${term} 包含空格,它们都会拆分模式。当您在 <> 表单中引入引号时,它可以防止在带有空格的 ${term} 上发生这种拆分,从而搜索不同的模式。

于 2012-08-24T20:07:22.067 回答
4

<SomeStuff>等同于glob "SomeStuff"(除了<>用于从文件句柄读取的所有歧义之外——请参阅perldoc perlop并查找I/O Operators那里)。因此,您的示例不等效。你应该使用

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

反而。

但是,至于为什么图案中的空间会有所不同:perldoc -f glob讲述故事。正常glob(因此<>通过 实现glob)将空格视为模式分隔符。该文档还提到File::Glob了它的功能bsd_glob,它不将空格视为模式分隔符。因此考虑改用这个:

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";

我刚刚创建的一些文件的可能输出:

[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
于 2012-08-24T20:08:34.193 回答