Recently I was faced with an annoying problem: I knew I had written a piece of code I now wanted to use, but didn't know where it was on my hard drive, or even what the file it was in could be called. I wanted something like BBEdit's multiple-file recursive grep, but alas, that searches only the data fork, and as we all know, MacPerl droplets keep their source in the resource fork -- and I was passably sure it was in a droplet! So I wrote this script, below, or at <http://www.lenzo.com/~sburke/pub/mac/macperl_grep.pl> While the part about accessing the resource fork might not make sense (unless you already know about such things, of course), I suggest that you read and understand at least most of the rest of the code, both for your own edification and so you can customize it. (A note: if you feed in a bad regexp (e.g. "(foo(" ), the script will harmlessly die, complaining about, yup, a bad regexp. So don't do that.) #!Perl # macperl_grep.pl 1998-04-10 Sean M. Burke (sburke@netadventure.net) # # Search given MacPerl files for lines matching a given regexp. # # A "MacPerl file" is very loosely defined as anything that # is a TEXT file, or is owned by (AKA was created by) MacPerl. # # Drop files or folders on this script (which you should resave as # a droplet). # # If you drop any folders on this script, their contents # will be recursed and only filenames matching a (second) given # regexp (if they are also TEXTs or created by MacPerl) will be # searched. # #! This is different from, say, the Multi-File Search in BBEdit in #! that this will search text resource #128 (where droplets et al. #! keep their source) in addition to data forks. # # I'm not calling this a general grepper for the Mac, because for # that I'd want to grep other kinds of resources besides just # TEXT resources (much less just TEXT #128) use Mac::Memory; use Mac::Resources; use File::Find; $debug = 0; # 0 = normal output, 1 = verbose, 2 = really verbose #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - exit unless @ARGV; @files = (); @directories = (); foreach(@ARGV) { if(-f $_) { push(@files, $_) } else { push(@directories, $_) } } $regexp = MacPerl::Ask('Regexp to search for in file content', ''); exit if $regexp eq ''; if(@directories) { $filename_regexp = MacPerl::Ask( 'Regexp to match filenames against', '.'); exit if $filename_regexp eq ''; } print "Starting to search for /$regexp/...\n"; # first, search specified files foreach(@files) { &grep_perl($_) } # recurse directories find(sub { unless($_ ne "Icon\cm" and ! /\.(txt|s?html?)$/si # TEXTs that are non-Perly and /$filename_regexp/oi and -f $File::Find::name) { print "Not looking at $File::Find::name\n" if $debug > 1; return; } # otherwise... &grep_perl($File::Find::name); } , @directories) if @directories; print "Done.\n\n"; exit; #-------------------------------------------------------------------------- sub grep_perl { my $SPEC = $_[0]; my $handle_128 = undef; print "Looking at $SPEC\n" if $debug; my($creator, $type) = MacPerl::GetFileInfo($SPEC); unless( $creator eq 'MrPL' or $creator eq 'McPL' or $type eq 'TEXT') { print " bad owner/creator; skipping.\n" if $debug; return; } my $refnum = FSpOpenResFile($SPEC, 1); Reslook: if(defined($refnum)) { $handle_128 = Get1Resource('TEXT', 128);# Look for a TEXT #128 if( $handle_128 ) { my @lines = split("\cm", $handle_128->get); CloseResFile $refnum; print scalar(@lines), " lines in $SPEC TEXT #128\n" if $debug; for (my $line_number = 0; $line_number < @lines; $line_number++) { next unless $lines[$line_number] =~ /$regexp/oi; chomp($lines[$line_number]); # may or may not be necessary print "$SPEC\xC5", 1 + $line_number, "\xC5$lines[$line_number]\n"; } # \xC5 = the MacAscii swoosh-equals return; # don't look in the data fork } else { # resource, but no TEXT #128 print " no text #128...\n" if $debug; CloseResFile $refnum; } } return unless -s $SPEC; # if we get this far, look in the data fork print " looking at $SPEC\'s data fork...\n" if $debug; if(open(IN, "$SPEC")) { local($_); # If you want to add heuristics to isolate just Perl scripts # and not other text files, do so here, then seek() back # to the start of the file. # Also maybe do newline conversion (by setting $/) if you're # net sure all your Perl files are in Mac newline (CR) format while(<IN>){ next unless /$regexp/oi; chomp($_); print "$_[0]\xC5$.\xC5$_\n"; } # \xC5 = the MacAscii swoosh-equals } close(IN); print " moving on...\n" if $debug; } __END__ ***** Want to unsubscribe from this list? ***** Send mail with body "unsubscribe" to mac-perl-request@iis.ee.ethz.ch