#!/usr/bin/perl # rp $pat $rpl file... # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # This program takes a perl pattern and scans thru the files for it. When it # is found, the file is "edited" so that all instances of the pattern $pat # are replaced by the string $rpl. The editing is done "in place", by copying # the text over to a /tmp/ file, and if any matches succeed, the /tmp/ file # is copied back to the original file. This method is like ed, and works for # multiply-linked files. At present, there is no provision for making a # backup copy, but it'd be easy enough to do if needed. # # Note some special cases, based on the name that we're called by: # frp matches only function calls. # vrp matches "variables", i.e., /\b$pat\b/ # Any other name will merely replace $pat with $rpl globally. # # We show the file names and the matches. Perhaps we need a -v option ... # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # $0 =~ s/.*\///; # # Check out the name we were called with: # $p1 = $p2 = $r1 = $r2 = ''; if ($0 eq 'frp') { # frp matches function calls. $p1 = '\b'; $p2 = '\s*\('; $r2 = '('; } elsif ($0 eq 'vrp') { # vrp matches variables. $p1 = '\b'; $p2 = '\b'; } $, = ' '; $pat = shift || die "Usage: $0 pattern replacement [filename]...\n"; $rpl = shift || die "Usage: $0 pattern replacement [filename]...\n"; foreach $f (@ARGV) { if ($f) { # print "File : $f\n"; if (open(F,"<$f")) { $t = "/tmp/fr_$$"; if (open(T,">$t")) { $m = 0; # Number of matches. while () { if (s/$p1$pat$p2/$r1$rpl$r2/g) { print; ++$m; } print T; } close(F); close(T); if ($m ) { print "=====> $f\n"; system "cp $t $f"; } system "rm $t"; } else { printf STDERR "Can't write \"$t\"\n"; } } else { printf STDERR "Can't read \"$f\"\n"; } } }