#/usr/bin/perl -w #Stringscan by Jeremy Price #Call with perl stringscan.pl "/full/directory/path/from/the/top" #Run through a directory structure, pick the strings out of files, hash them, #sort them and then print them out with references to the files they came from. #Bugs: Will fail badly on files which include a ";" ie a ; in quotes. use strict; use diagnostics; #Download this from CPAN with 'perl -MCPAN -e "install File::Recurse" use File::Recurse; my $cd = $ARGV[0]; #The directory to be scanned, supplied on the command line my @dc; #Directory contents. A list of files in dir my %fl; #String locations (which files are they in?) my $ft; #The type of file we are examining #ft is filetype, a hash of the file languages and the extension to identify them my %ft=( 'c'=> '\.h$|\.c$', 'perl'=> '\.pl$' ); #An associative array, keyed by filetype, of regular expressions to find the strings. #To add more, add another 'filetype'=>'regexp' my %search=( 'c'=>'(\"[^;]*)', 'perl'=>'(\"[^;]*)' ); my %vars; #A cheap way of maintaining a list so that each item is unique print "\nNow scanning for all files in directories below: $cd"; my %files = &Recurse([$cd], {match => join('|',keys %ft)}); foreach my $dir (sort keys %files) { foreach my $file (@{ $files{$dir} }) { push @dc, "$dir/$file"; }} FILE: foreach my $i (@dc){ #WindBlows hack, comment out if you are on a UFS (Unified File System). $i=~ s/\//\\/g; #Try to detect the type of file we are examining $ft='none'; #Default (fall through) option foreach my $j ( keys %ft ) {$ft=$j if $i=~ /$ft{$j}/;} #Bail if we couldn't figure it out. next FILE if $ft eq 'none'; open(FH, "<$i") || die "can't open file $i: $!"; print "\n\nThe strings in $i\nvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n"; { local($/)=undef; #Change the record separator to nothing for a short while my $filedata=; #read the whole file into filedata while ($filedata=~ /$search{$ft}/g){ #Apply the correct regex based on the file type ($ft) add_func($1,$i); #Add it to the hash (see below) } } close FH; } #Output the hash print "\n\nBelow is a list of all the strings found, and then the files they were found in\n"; foreach my $i ( keys %fl ) { print "\n\n\n\nThis is the string: \n$i"; print "\n\nIt was found in these files:\n "; print join(',\n', @{ $fl{$i} }); } sub add_func(){ my $string=$_[0]; my $file=$_[1]; #Push the filename onto a list which is referenced by the string push @{ $fl{$string} },$file; }