tools - utils to find files not begin with a pattern but contains b pattern

in my working environment, the home directory may contains some speical cache directory where you others may not be able to use.  So normally we don't want to go through the directory nor we want to display result in that directory;

I am writting a small perl script to help me do that :

use warnings;
use strict;
use Carp;

use File:Find;
my $file = pop @ARGV;
my $exclude = pop @ARGV || "";

croack "syntax: $0 [\$ignore_prefix] \$file" unless defined $file && $file ne "";

@ARGV = (".") unless @ARGV;

find (\$process_file, @ARGV);
sub process_file {
  if ($exclude ne "") { 
   if ($File::Find::name !~ /^(?:$exclude)/ && $File::Find::name =~ /$file) { 
     print $File::Find::name, "\n";
   }
 } elsif ($File::Find::name =~ /$file/) { 
     print $File::Find::name, "\n";
  }

}
 

However, I used to think that it might work if I use the expression and use the negative lookback assertion (anchor), and I wrote the following code.

sub process_file { 
  if ($exclude ne "") { 
     if ($File::Find::name =~ /^(?<!$exclude).*$file)/) { 
        print $File::Find::name, "\n";
     } elsif ($File::Find::name =~ /$file/) { 
	print $File::Find::name, "\n";
     }
  }
}

Guess why, given a pattern which is ./.oldFiles/anyfile, if the $exclude =  ./.oldFiles, and $file = anyfile,  the problem it is some greedy match, so .* may extend to matched hte ./.oldFiles. so you end up errors.

the above code works in a callback manner, where it goes to every folder and check if that current check file matches, sometimes we don't want to go into some folder (due to permission or performanc), we can choose to use readdir, opendir, rewinddir calles. 

here is the code: 

use strict;
use Carp;

# from Metacpan.org
#   https://metacpan.org/module/IO::File
# File::Fu - File and directory objects


# more details on opendir
#   http://perldoc.perl.org/functions/opendir.html
# more details on readdir
#   http://perldoc.perl.org/functions/readdir.html

my $file = pop @ARGV;
my $exclude = pop @ARGV || "";

croak "$0: \$[exclude_file] \$[file]" unless defined $file && $file ne "";

process_dir(".");

sub process_dir {
    my $dir = shift;
    return unless defined $dir;
    opendir (my $d_h,  $dir) || die "Cannot open $dir $!";
    if ($exclude ne "") {
        my @files =  grep { -f "$dir/$_" && !/$exclude/ && /$file/ } readdir($d_h);
        for my $match (@files) {
            print "$dir/$match", "\n";
        }
        rewinddir($d_h);

        my @sub_dirs = grep { -d "$dir/$_" && !/^\.$/ && !/^\.\.$/ && !/$exclude/} readdir($d_h);
        for my $sub_dir (@sub_dirs) {
            process_dir($dir . "/" . $sub_dir);
        }
    } else {
        my @files = grep { -f "$dir/$_" && /$file/ } readdir ($d_h);
        for my $match (@files) {
            print "$dir/$match", "\n";
        }
        rewinddir($d_h);

        my @sub_dirs = grep { -d "$dir/$_" && !/^\.$/ && !/^\.\.$/} readdir($d_h);
        for my $sub_dir (@sub_dirs) {
            process_dir($dir . "/" . $sub_dir);
        }

    }

}

猜你喜欢

转载自joe-bq-wang.iteye.com/blog/1678184
今日推荐