1

我正在使用 perl 在目录中查找一些 kml 文件。这些文件位于 /Data/######/。其中###### 是一个 6 位数字。所有的 kmls 都是相同的 6 位数字,无论它位于什么文件夹中... /Data/######/######_REP.kml

问题是我还有另一个文件夹 /Data/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
4

2 回答 2

3

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

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

那应该解决它。

于 2013-02-07T15:09:49.160 回答
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 数据
数据:
123456 654321 质检

数据/123456:
123456_REP.kml

数据/654321:
654321_REP.kml

数据/质量控制:
123456_REP.kml 654321_REP.kml

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

$ ./find-kml 数据
数据/123456/123456_REP.kml
数据/654321/654321_REP.kml
于 2013-02-07T16:02:24.203 回答