【问题标题】:How can I test if a filename matching a pattern exists in Perl?如何测试 Perl 中是否存在与模式匹配的文件名?
【发布时间】:2011-04-27 04:53:12
【问题描述】:

我可以在 Perl 中做这样的事情吗?文件名的含义模式匹配并检查它是否存在。

    if(-e "*.file")
    {
      #Do something
    }

我知道要求系统列出当前文件的更长解决方案;将其作为文件读取,然后推断文件是否存在。

【问题讨论】:

    标签: perl file match exists glob


    【解决方案1】:

    您可以使用glob 返回一个包含所有匹配模式的文件的数组:

    @files = glob("*.file");
    
    foreach (@files) {
        # do something
    }
    

    如果你只是想知道匹配模式的文件是否存在,你可以跳过赋值:

    if (glob("*.file")) {
        # At least one file matches "*.file"
    }
    

    【讨论】:

    • 为了完整,你也可以foreach (glob("*.file")) { something }...
    • 但我无法将正则表达式放在那里。我可以使用正则表达式吗?
    • @alertjean 不,您必须打开目录并使用正则表达式手动扫描文件名。 glob 只支持传统的shell wild cards
    • @Jean 您可以在 glob 之后使用 grep,例如grep /g/, glob "*.txt" 将为您提供名称中包含“g”的所有 .txt 文件。
    • fwiw, glob 文档说:“如果非空大括号是 glob 中使用的唯一通配符,则不匹配文件名,但可能会返回许多字符串。” i> - 所以这个解决方案只有在存在通配符的情况下才有效。太糟糕了。
    【解决方案2】:

    在 *nix 系统上,我使用了以下方法,效果很好。

    sub filesExist { return scalar ( my @x = `ls -1a 2> /dev/null "$_[0]"` ) }
    

    它回复找到的匹配数,如果没有,则返回 0。使其易于在“if”条件中使用,例如:

    if( !filesExist( "/foo/var/not*there.log" ) &&
        !filesExist( "/foo/var/*/*.log" ) &&
        !filesExist( "/foo/?ar/notthereeither.log" ) )
    {
        print "No matches!\n";
    } else {
        print "Matches found!\n";
    }
    

    您可以使用的确切模式取决于您的 shell 支持的内容。但大多数 shell 支持使用 '*' 和 '?' - 在我见过的任何地方,它们的意思都是一样的。当然,如果您删除了对“标量”函数的调用,它将返回匹配项——这对于查找这些变量文件名很有用。

    【讨论】:

    • 最好避免像这样调用 shell,因为首先你可能并不总是在你测试的那种系统上运行,其次可能很容易出现某人有非标准的情况影响功能的二进制或环境变量。相关,如果你是 $LESS env-var,那么 man 会受到其中的选项的影响。
    【解决方案3】:

    在 Windows 上,我不得不使用 File::Glob::Windows,因为分隔反斜杠的 Windows 路径似乎不适用于 perl 的 glob。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 2010-10-13
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多