#!/usr/bin/perl use strict; use File::Spec; use File::Basename; use Getopt::Long; sub canon($) { my $path = shift; my $cur = File::Spec->curdir(); my $up = File::Spec->updir(); my @parts = File::Spec->splitdir("$path"); if (($parts[0])&& ($parts[0] ne $cur)&& ($parts[0] ne $up)) { $path = $cur.File::Spec->catfile('',$cur, @parts); } return $path; } sub getfiles($) { my $opath = shift; local *DIR; my @files = (); my @pathtotreat = ($opath); my $cur = File::Spec->curdir(); my $up = File::Spec->updir(); while (@pathtotreat) { my $thepath = shift @pathtotreat; if (-d "$thepath") { if (opendir(*DIR,"$thepath")) { while (my $f = readdir(*DIR)) { if (($f ne $cur)&&($f ne $up)) { my $fullpath = File::Spec->catfile("$thepath","$f"); if (-d "$fullpath") { push @pathtotreat, "$fullpath"; } else { push @files, canon("$fullpath"); } } } closedir(*DIR); } else { print STDERR "$thepath: $!\n"; } } elsif (-e "$thepath") { push @files, canon("$thepath"); } } return @files; } sub matchMotif($\@) { my $filename = shift; my $result; my $or = 0; foreach my $motif (@{$_[0]}) { if ($motif eq '&') { $or = 0; } elsif ($motif eq '|') { $or = 1; } else { my $localresult = 0; if ($motif =~ /^\^(.*)$/) { my $m = "$1"; $localresult = ($filename !~ /^$m$/); } else { $localresult = ($filename =~ /^$motif$/); } if (defined($result)) { if ($or) { $result = $result || $localresult; } else { $result = $result && $localresult; } } else { $result = $localresult; } $or = 0; } } return $result; } my @expr = (); my $negation = 0; if (!GetOptions('name=s' => sub { if ((@expr)&&($expr[$#expr] ne '&')&&($expr[$#expr] ne '|')&& ($expr[$#expr] ne '!')&&($expr[$#expr] ne '^')) { push @expr, '&'; } push @expr, $_[1]; }, 'nname=s' => sub { if ((@expr)&&($expr[$#expr] ne '&')&&($expr[$#expr] ne '|')&& ($expr[$#expr] ne '!')&&($expr[$#expr] ne '^')) { push @expr, '&'; } push @expr, '!', $_[1]; }, 'path=s' => sub{ if ((@expr)&&($expr[$#expr] ne '&')&&($expr[$#expr] ne '|')&& ($expr[$#expr] ne '!')&&($expr[$#expr] ne '^')) { push @expr, '&'; } push @expr, '^', $_[1]; }, 'npath=s' => sub{ if ((@expr)&&($expr[$#expr] ne '&')&&($expr[$#expr] ne '|')&& ($expr[$#expr] ne '!')&&($expr[$#expr] ne '^')) { push @expr, '&'; } push @expr, '!', '^', $_[1]; }, 'o' => sub { push @expr, '|' if (@expr); }, 'a' => sub { push @expr, '&' if (@expr); }, 'not' => sub { if ((@expr)&&($expr[$#expr] ne '&')&&($expr[$#expr] ne '|')&& ($expr[$#expr] ne '!')&&($expr[$#expr] ne '^')) { push @expr, '&'; } push @expr, '!'; }, )) { exit(1); } my $directory = shift @ARGV || die("no directory specified\n"); die("no pattern specified\n") unless (@expr); foreach my $m (@expr) { $m =~ s/([.-])/\\$1/g; $m =~ s/\*/.*/g; $m =~ s/\?/\\./g; } my @files = getfiles("$directory"); foreach my $file (@files) { if (matchMotif($file,@expr)) { print "$file\n"; } } exit(0);