在Perl中查找与模式匹配的文件

时间:2013-07-28 12:39:32

标签: regex perl

我通过-f选项获取用户输入,无论他输入什么,相应地递归搜索文件。

我的问题是:当用户输入“tmp *”时,它也会搜索“abctmp”,“xyztmp”等。我想要做的是,只有以tmp开头的文件才会出现。 简而言之,无论用户输入什么文件都应该推送到数组。

目前我正在这样做,但我确信这有一些优雅,简短的方法。

#! /perl/bin/perl
use strict;
use warnings;
use File::Find;
use getopt::Long;

my $filename="tmp*.txt";
find( { wanted     => \&wanted,
        preprocess => \&dir_search,
}, '.');

sub wanted{
    my $regex;
    my $myop;
    my @mylist;
    my $firstchar= substr($filename, 0,1); # I am checking first character. 
                                           # Whether it's ".*tmp" or just "tmp*"

    if($filename=~ m/[^a-zA-Z0-9_]/g){     #If contain wildcard
        if($firstchar eq "."){             # first character "."
            my $myop  = substr($filename, 1,1);
            my $frag  = substr($filename,2);
            $filename = $frag;
            $regex    = '\b(\w' . ${myop}. ${filename}. '\w*)\b'; 
            # Has to find whatever comes before 'tmp', too
        } else {
            $regex    = '\b(' . ${myop}. ${filename}. '\w*)\b'; 
            # Like, "tmp+.txt" Only search for patterns starting with tmp
        }
        if($_ =~ /$regex/) {
            push(@mylist, $_);
        }
    } else {
    if($_ eq $filename) { #If no wildcard, match the exact name only.
        push(@mylist, $_);
    }
}

}

sub dir_search {
    my (@entries) = @_;
    if ($File::Find::dir eq './a') {
        @entries = grep { ((-d && $_ eq 'g') || 
                      ((-d && $_ eq 'h')  || 
                     (!(-d && $_ eq 'x')))) } @entries; 
    # Want from 'g' and 'h' folders only, not from 'x' folder
    }
    return @entries;
}

另一件事是,我想只搜索'.txt'文件。我应该把这个条件放在哪里?

1 个答案:

答案 0 :(得分:1)

#!/perl/bin/perl

sub rec_dir {
    ($dir,$tmpfile_ref) = @_;
    opendir(CURRENT, $dir);
    @files = readdir(CURRENT);
    closedir(CURRENT);

    foreach $file (@files) {
        if( $file eq ".." || $file eq "." ) { next; }
        if( -d $dir."/".$file ) { rec_dir($dir."/".$file,$tmpfile_ref); }
        elsif( $file =~ /^tmp/ && $file =~ /\.txf$/ ) { push(@{$tmpfile_ref},$dir."/".$file); }
    }
 }

 @matching_files = ();
 $start_dir = ".";
 rec_dir($start_dir,\@matching_files);
 foreach $file (@matching_files) { print($file."\n"); }

我没有测试它。除非印刷错误,我认为它会起作用。