1

ディレクトリ内のいくつかの kml ファイルを見つけるために perl を使用しています。ファイルは /Data/######/ にあります。###### は 6 桁の数字です。すべての kml は、それが入っていたフォルダーの同じ 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

少なくとも 2 つの方法で、やりたいことを実行できます。

完全なパスでフィルタ

コールバックを呼び出すたびに、スカラー$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 QC

データ/123456:
123456_REP.kml

データ/654321:
654321_REP.kml

データ/QC:
123456_REP.kml 654321_REP.kml

上記のプログラムのいずれかを実行すると、次の出力が生成されます。

$ ./find-kml データ
データ/123456/123456_REP.kml
データ/654321/654321_REP.kml
于 2013-02-07T16:02:24.203 に答える