提取文件名

时间:2011-12-05 23:30:43

标签: regex perl

我正在编写一个脚本,该脚本从目录中获取文件列表,打开每个文件,然后搜索包含扩展名为.zip的文件名的行。然后我想从行中删除文件名。这是我的代码:

foreach (@fnames) {
    chomp ($_);
    open FILE, '<', "$_";
    @archives = grep { /.+?\.zip/ } <FILE>;

    foreach (@archives) {
        if ($_ =~ /("|>)(.+?)("|<)/) { push @files, $2; }
    }
}

我从中提取数据的文件将包含双引号或尖括号之间的.zip文件名。此代码没有返回任何内容,但我知道文件名存在。如果我在终端上做grep我可以看到所有这些,但是Perl中的grep并没有给我任何东西。有什么想法吗?

2 个答案:

答案 0 :(得分:6)

可能出错了:

  • @fnames为空,因为代码中的某些错误您不是 展示。
  • open FILE, ...失败,但由于您没有检查返回值 在open,它无声地失败,因此你不知道它。使用open ... or die $!
  • 您的输入中有大写字母,例如ZIP,不要使用 grep中的/i ignore case选项。顺便说一下,.+?开头 是相当无用的,除非你期望不需要的字符串开头 .zip(即它只检查之前至少有一个字符)。
  • 第二个循环中的if语句只会抓取第一个 匹配。

另外:

  • 您应该使用带open的词法文件句柄。
  • 如果你还没有这样做,你应该使用严格和警告。
  • 在正确的词汇范围内
  • my @archivesmy @files会有所帮助 保证你获得并保存你想要的数据。
  • $_ =~ /.../可以简单地编写/.../以提高可读性 (IMO)。
  • 您(确实)不需要转换变量。
  • ("|>)是一种冗长的说法[">]
  • grep是冗余处理。你可以这样做:

while (<FILE>) {
      push @files, /[">](.*\.zip)["<]/ig;
}

简而言之:

my @files;
foreach my $file (@fnames) {
    chomp $file;
    open my $fh, '<', $file or die $!;
    while (<$fh>) {
        push @files, /[">](.*\.zip)["<]/ig;
    }
}
print "File names found: @files\n";

答案 1 :(得分:0)

在您的脚本中,您没有输出任何内容,只是在更改数组中的元素。您必须print您的行,或使用Tie::File直接作为数组访问每个文件。