Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

How to find a specific pattern recursively in all the files and subfolder files of a directory .

by perladdict (Chaplain)
on Jun 07, 2007 at 15:26 UTC ( #619827=perlquestion: print w/replies, xml ) Need Help??
perladdict has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
I am working on a task to find a pattern as "/v_dialer" in the vob-tag /v_dialer.
Here /v_dialer is a vob database which contains thousands of files and subdirectories,
how can i change the paths of those subdirectories and how can i exmine each files and subdirectory files for
matching "/v_dialer" pattern.Before posting this i go through all the perl doc like as File::Find:name..etc..etc.
those doc only related to show the file name paths which contains "/v_dialer" pattern.
command prompt:$ ls -R /v_dialer ./3rdparty/src/gettext-0.14.1/gettext-tools/examples/po: ----------------------------------------------------------- LINGUAS gettext-examples.pot sr.po ja.po stamp-po sv.po af.po nl.po tr.po ca.po pl.po de.po remove-potcdate.sin zh_CN.po es.po ro.po fr.po sk.po ./3rdparty/lib: ---------------------------------------------------------------------- +--- charset.alias libiberty.a libstdc++.a gcc libfl.a libiberty2.a gettext libgcc_s.1 libiconv.a libasprintf.a libintl.a libbfd.a libgettextpo.a libsupc++.a libopcodes.a libcharset.a liby.a
monks waiting for your solutions for this......
  • Comment on How to find a specific pattern recursively in all the files and subfolder files of a directory .
  • Download Code

Replies are listed 'Best First'.
Re: How to find a specific pattern recursively in all the files and subfolder files of a directory .
by shmem (Chancellor) on Jun 07, 2007 at 17:57 UTC

    Taken directly from the good old pink Camel book - pipegrep:

    #!/usr/bin/perl die "usage: pipegrep pattern command files\n" unless @ARGV; $debugging = 0; $ARGV[0] eq '-i' && do { shift; $insensitiv = 1 }; if ($ARGV[0] eq '-l') { shift; $action = <<'EOF'; print $file,"\n"; next file; EOF } else { $action = <<'EOF'; print $file,"\t:",$_; EOF } # get the pattern an protect the delimiter we'll use. $pat = shift; $pat =~ s/!/\\!/g; # get command and make shure it has a {}. $cmd = shift; $cmd .= ' {}' unless $cmd =~ /{}/; # modify each filename into the corresponding command. for (@ARGV) { $file = $_; $_ = $cmd; s/{}/$file/; s/$/ |/; } # generate the program. $prog = <<EOF; file: foreach \$file (\@ARGV) { open(FILE,\$file) || do { "Can't open \$file: \$!\\n"; next; }; while(<FILE>) { EOF if($insensitiv) { $prog .= <<EOH; if (m!$pat!i) { EOH } else { $prog .= <<EOG; if (m!$pat!) { EOG } $prog .= <<EOT; $action; } } } EOT print $prog if $debugging; # and finally, do it. eval $prog; die $@,"\n" if $@;

    That might be the oldest script in my toolbox. Looks tchrist-ish, but could as well be merlyn's. T'was perl 4, then, hence no strict nor warnings. I've been too lazy to rewrite it - it just works :-)

    Example: get symbols from shared object (*.so) or archive (*.a) files:

    pipegrep -l symbol nm *.so *.a

    where symbol is the symbol you want to find.

    <update> ...and to do that recursively

    pipegrep -l symbol nm `find /usr/lib -name \*.so -o -name \*.a`
    Replacing find(1) with File::Find inside the script is left as an exercise to the reader. To recursively list files containing a pattern without running the files through a filter, just use
    grep -r pattern directory



    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: How to find a specific pattern recursively in all the files and subfolder files of a directory .
by zentara (Archbishop) on Jun 07, 2007 at 17:05 UTC
    Here is a little utility I use called zzgrep( to avoid conflict with zgrep).
    #!/usr/bin/perl use warnings; use strict; use File::Find; $|++; # defaults are case-insensitive, no recurse, open and search files (no +t filename) if ($#ARGV < 0){die "Usage zgrep 'pattern' c(case sensitive optional) +r(recurse optional) n(search name only optional) examples: zgrep 'debug me' r will recursively search all files for 'debug me'\n"; } my ($recurse, $name, $case) =(0,0,0); if( grep{/\bn\b/} @ARGV ){@ARGV = grep { $_ ne 'n' } @ARGV; $name = 1 +}; if( grep{/\br\b/} @ARGV ){@ARGV = grep { $_ ne 'r' } @ARGV; $recurse = + 1 }; if( grep{/\bc\b/} @ARGV ){@ARGV = grep { $_ ne 'c' } @ARGV; $case = 1 +}; #print "$name $recurse $case @ARGV\n"; my $path = '.'; #only accept 1 search string, so quote phrases my $search = $ARGV[0]; my $regex; #defaults to case insensitive if ($case){$regex = qr/\Q$search\E/} else{$regex = qr/\Q$search\E/i} # use s modifier for multiline match find (sub { #skip directories which begin with 1 if (-d && $_ =~ /^1.*$/) { $File::Find::prune = 1; return; } if( ! $recurse ){ my $n = ($File::Find::name) =~ tr!/!!; #count slashes in file return $File::Find::prune = 1 if ($n > 1); } return if -d; return unless (-f and -T ); if($name){ if ($_ =~ /$regex/){print "$File::Find::name\n"}; }else{ open (FH,"< $_"); while(<FH>){ print "$File::Find::name: $. :$_\n " if /$regex/; } close FH; } }, $path);

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://619827]
Approved by clinton
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (6)
As of 2018-04-22 21:19 GMT
Find Nodes?
    Voting Booth?