简体   繁体   中英

how to exclude files having extension “.doc or .jar” from search using FILE::FIND in perl

I am facing two problems .

1)I am searching a directory for certain keywords and the directory contains files with many extension like .java .sql .ksh .pl .jar etc.. . Now my problem is i dont want to search the files having .jar or .doc or .docx . currently my code looks like below

use strict;
use warnings;
use File::find;

my $dir = "C:\DURAB\";
my $out = "output.txt";
open my $out, ">", "output.txt";
find(\&printFile,$dir);                                       

sub printFile {
   my $element = $_;

   if(-f $element && $element =~ /\.*$/){ 

      open my $in, "<", $element or die $!;
      while(<$in>) {
         if (/\Q$searchString\E/) {
       my $last_update_time = (stat($element))[9];
            my $timestamp  = localtime($last_update_time);
            print $out "$File::Find::name". "     $timestamp". "     $searchString\n";
            last;
           }
         }

      }
    }

in this it is searching for all the files now i want to restrict the search so that no need of searching .jar,.exe ,.doc kind of extensions.

2) while searching the directory i have many subdirectories . i dont want to search in the directories having name obsolete or retired in them (for example obsolete_dr , retired_as ) how can i achieve this using file::find

i think i am little bit confusing actually below is the output i need

from the above code $file::find::name displays the file path if this file path contains obsolete or retired then that output should not be shown.

for example i got path like

c:\DURAB\ASD\OBSOLETE_EC23\sirgu.sql and c:\DURAB\AS\drive.ksh

from the above first path should not be displayed since it is having the word obsolete.

i think now i am clear. Thanks in advance

return if /\.(?:docx?|jar)\z/;

and

if (/obsolete|retired/) {
   $File::Find::prune = 1;
   return;
}

To reject the unwanted files you should check the name of the file using a regular expression and return from the print_file subroutine if necessary.

To ignore directories containing obsolete or retired you should check whether the node is a directory whose name contains either of these words. If so, then setting $File::Find::prune to a true value will prevent File::Find from recursing into it.

Note that I have used use autodie which will implicitly raise an exception if an open call doesn't work, and File::stat allows by-name access to the fields of the result of a call to stat .

I'm not sure what you meant by your regex /\\.*$/ which will match any string as it requires zero or more trailing dots, but this code also excludes file names that end with a dot.

use strict;
use warnings;

use File::Find;
use File::stat;
use autodie;

my $dir = 'C:\DURAB';
my $search_string = 'ABCDEF';

my $out = 'output.txt';
open my $outfh, '>', $out;

find(\&print_file, $dir);

sub print_file {

  if ( -d and /obsolete|retired/i ) {
    $File::Find::prune = 1;
    return;
  }

  return unless -f and not /\.(exe|doc|docx|exe|)$/;

  my $element = $_;

  open my $in, '<', $element;

  while (<$in>) {
    if ( /\Q$search_string\E/ ) {
      my $last_update_time = stat($element)->mtime;
      my $timestamp = localtime $last_update_time;
      printf $outfh "%s     %s     %s\n",
          $File::Find::name,
          $timestamp,
          $search_string;
      last;
    }
  }
}

Change this line

 if(-f $element && $element =~ /\.*$/){ 

to this

 if( (-f $element && $element !~ /\.(jar|docx?)$/i) || ( $File::Find::dir !~ /(obsolete|retired)/i) ){ 

a good guide: http://www.perlmonks.org/?node_id=217166

Regards,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM