如何排除Find()中的文件

时间:2013-02-07 15:03:14

标签: regex perl

我使用perl在目录中查找一些kml文件。文件位于 /数据/######/。 其中######是一个6位数字。 所有kmls都是相同的6位数字的任何文件夹... /数据/ ###### / ###### _ REP.kml

问题是我有另一个文件夹 /数据/ QC / ###### / 同样具有相同的kmls。我想从我的搜索中忽略该QC文件夹中的任何内容。

我的代码:

    sub repmatch{
    Push(@filelist,$File::Find::name) if ($File::Find::name =~ m\d{6}\/\d{6}_REP.kml$/)
    }

    find(\&repmatch,$dir) # $dir is my directory I passed in

2 个答案:

答案 0 :(得分:3)

在repmatch子程序中,添加(推送前):

if ( $_ eq 'QC' ) {
    $File::Find::prune = 1;
    return;
}

那应该解决它。

答案 1 :(得分:1)

你可以通过至少两种方式做你想做的事。

按完整路径过滤

在每次调用回调时,标量$File::Find::name包含完整路径。您想要的文件的直接父级必须是6位数字,并且该文件必须是相同的数字加上后缀。

看起来像这样。

#! /usr/bin/env perl

use strict;
use warnings;

use File::Find;

my $dir = @ARGV ? shift : "/Data";

my @filelist;
sub repmatch {
  push @filelist, $File::Find::name
    if $File::Find::name =~ m!/(\d{6})/\1_REP.kml$!;
}

find \&repmatch, $dir;

print "$_\n" for @filelist;

要忽略的修剪目录

在回调中设置$File::Find::prune会在搜索的其余部分中删除当前子树。

修剪可让您的过滤器更简单。在每次调用回调时,$_都包含文件的名称,并且可以针对数字后跟后缀模式测试生存到此时的任何内容。如果要锁定对直接父级名称的约束,可以使用上一个程序中的测试。

#! /usr/bin/env perl

use strict;
use warnings;

use File::Find;

my $dir = @ARGV ? shift : "/Data";

my @filelist;
sub repmatch {
  $File::Find::prune = 1 if /^QC/ && -d;
  push @filelist, $File::Find::name
    if /^\d{6}_REP.kml$/;
}

find \&repmatch, $dir;

print "$_\n" for @filelist;

样本输出

给定

的目录结构
$ ls -R Data
Data:
123456  654321  QC

Data/123456:
123456_REP.kml

Data/654321:
654321_REP.kml

Data/QC:
123456_REP.kml  654321_REP.kml

运行上述任一程序会产生以下输出。

$ ./find-kml Data
Data/123456/123456_REP.kml
Data/654321/654321_REP.kml