来自“ls”输出的文件名的Perl通配符匹配

时间:2017-02-03 23:58:51

标签: regex perl pattern-matching

#!/usr/bin/perl

my @allFiles=`ls *.gz`;

for my $file (@allFiles) {
    if ($file =~ '0000*.gz') {
         print $file;
    }
}

我正在尝试上面的代码来打印所有前缀为0000的文件名。如00001.gz,00002.gz等

1 个答案:

答案 0 :(得分:1)

正则表达式中与shell wildcard *相当的结尾是.** 量词意味着它之前的模式匹配"零或更多"时间和.表示"任何角色,"见Regular Expressions in perlre。但是因为看起来你想要在零之后某些东西然后使用.+来匹配任何角色一次或多次。要匹配文字句点,请将其\.

接下来,没有理由使用外部命令来执行操作。在Perl中

my @allFiles = glob "*.gz";

文档最后链接。

最后,始终启用警告和严格。

use warnings;
use strict;

my @allFiles = glob "*.gz";

foreach my $file (@allFiles) {
    if ($file =~ /^0000.+\.gz/) {
        print "$file\n";
    }
}

正则表达式模式匹配:0000位于字符串的开头(^),后跟任何匹配一次或多次的字符(.)({{1} }),然后是文字句点(+)和文字\.。请注意,gz表示.+ 匹配一次或多次,不一定是相同的字符。

根据您的实际需要和目录内容进行调整。例如,如果您希望只有零后跟数字的文件,则需要.。要捕获文件/^0000\d+\.gz/,您还需要在一串数字后允许非数字,例如00001a.gz

有关正则表达式教程和perlretut的信息,请参阅glob,有关名称中包含空格的内容,请参见File::Glob

还有其他方法可以做到这一点。例如,您需要过滤文件名列表,所以

/^0000\d+.*\.gz/

my @files = grep { /^0000.+\.gz/ } glob "*.gz"; 位于grep强加的列表上下文中,因此它返回与其匹配的所有文件的列表。 (在标量上下文中,它遍历它们。)glob块中的代码为每个运行,如果它的值为true则该元素通过。它是相同的正则表达式,默认情况下应用于$_ variable,它是隐式迭代器(并且别名为当前处理的元素)。所以grep 返回所需的列表。

对于您的具体示例,即使只是这样做

grep

这会在my @files = glob "0000[0-9].gz"; print "$_\n" for @files; 之后使用一位数提取所有文件,然后0000

查看已关联的.gz文档中已接受的元字符列表。