perl glob< > (明星)操作员返回意外结果?

时间:2014-05-13 20:27:57

标签: perl glob

我正在使用

my $file = <*.ext>;

在Perl中运行以测试文件是否存在(在这种情况下,我需要知道当前工作目录中是否存在带.ext的文件,否则我不继续)并且如果它没有&#则抛出错误39;吨。如:

my $file = <*.ext>;
if (-e $file) {
    # we are good
}
else {
    # file not found
}

正如您所看到的,我将带来&lt; *。ext&gt;的输入。在标量$变量中,而不是@array。这可能不是一个好主意,但它一直在为我工作,直到现在我花了一段时间搞清楚我的代码失败的地方......这似乎就是这样。

似乎在切换目录时(我在Windows机器上使用&#34; chdir&#34 ;,)当前工作目录正常切换但是glob操作符的输入是非常未定义的,并且会查看以前的目录,或者保留过去的价值观。

我已经能够通过

来解决这个问题
my @file = <*.ext>;
if (-e $file[0]) {
}

我想知道是否有人可以解释这一点,因为我无法找到glob运算符的返回值被定义为数组或标量的位置(如果只有一个文件,等)

试着在这里学习,以避免未来的错误。这是要求它在Windows上的Perl而不是我经常要做的事情,因此我在这种情况下的经验非常薄。 (更多Python / C ++人。)

感谢。

2 个答案:

答案 0 :(得分:4)

perldoc -f glob解释了这种行为

  

在列表上下文中,返回EXPR值的文件名扩展(可能为空)列表,例如标准的Unix shell / bin / csh。在标量上下文中,glob遍历这样的文件名扩展,当列表用完时返回undef。

所以你使用的迭代器版本应该与while一起使用来循环它(一直到它耗尽)。 因为您显然希望使用列表上下文仅获得第一个值,

my ($file) = <*.ext>;

答案 1 :(得分:0)

mpapec已经涵盖了glob背景下有关行为的perldoc scalar文档。

但是,我想补充一点,您可以将glob直接放在if

中来简化逻辑
if (<*.ext>) {
    # we are good
}
else {
    # no files found
}

-e的测试是多余的,因为glob如果文件不存在则不会返回该文件。此外,如果要对找到的文件实际执行操作,可以在if

中捕获它们。
if (my @files = <*.ext>) {