#! /usr/bin/perl # ==================================================================== # @(#) Make a series of changes to a group of files # ==================================================================== # $What: <@(#) ped> $ # # written by David Boldt Oct 28, 1998 # Revisions: # better error handling Jun 5, 2001 # -------------------------------------------------------------------- $BAK = '~'; # suffix for backup files $USAGE = "USAGE: $0 file ... Apply a series of edits to one or more files. If the file ends up different, save the orignal with a $BAK suffix. The changes to be applied are listed at the bottom of this program, and can easily be modified \n"; die $USAGE if ($#ARGV == -1); # exit if no files given while () { next if /^#/; # skip comments next if /^\s*$/; # skip empty lines chop if /\n$/; # pull off EOL if (/^\^/) { # if a line starts with ^, use that as delimiter s/^\^//; # remove leading ^ s/\^\s*$//; # remove trailing ^ s/\\\^/\0/g; # handle escaped ^ chars by translating to nulls s/\\n/\n/g; # newlines ($old,$new) = split(/\^/); $old =~ s/\0/^/g; # turn nulls back to ^ $new =~ s/\0/^/g; } else { ($old,$new) = split(/\s+/,$_,2); # if > 2 words, new gets them } push(@changes, "$old\n$new"); } foreach $file (@ARGV) { # for each file on command/line... # make sure file exists unless (-f $file) { warn "file '$file' does not exist.\n"; next; } if (-l $file) { warn "skipping link '$file'.\n"; next; } # two levels of backup rename ("${file}$BAK", "${file}$BAK$BAK") if (-f "${file}$BAK"); # link the file to the name of backup file link ($file, "${file}$BAK") || die "unable to link file '$file' to '${file}$BAK'\n"; if ($file =~ m%/%) { ($temp = $file) =~ s%([^/]+)$%.-$1%; } else { $temp = ".-$file"; } open (FILE,"<$file"); open (NEW,">$temp") || die "unable to create new file '$temp'/n"; # make the changes on the curent file $modifications = 0; while () { # for each line in file ... foreach $change (@changes) { ($old, $new) = split("\n", $change); $modifications += s/$old/$new/ig; } print NEW; # print whatever we have at this point to new file } close(FILE); close(NEW); if ($modifications == 0) { # if no changes, delete link and temp file unlink ("${file}$BAK", $temp); warn "file '$file' unmodified.\n"; } else { # if changes were made, clone the permissions and ownership &dupemod("${file}$BAK", $temp); rename($temp, $file); $s = 's' if ($modifications != 1); # english plurals warn "file '$file' updated ($modifications change$s).\n"; } } # -------------------------------------------------------------------- # -- duplicate the owner, group and permissions of a file sub dupemod { local($fromfile, $tofile) = @_; local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime, $mtime,$ctime,$blksize,$blocks); ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime, $mtime,$ctime,$blksize,$blocks) = stat($fromfile); chown $uid, $gid, $tofile; chmod $mode, $tofile; #utime $atime, $mtime, $tofile; # we could reset timestamp too! } # -------------------------------------------------------------------- # -------------------------------------------------------------------- # Edit changes go after the END line (case-insensitve) ... # ex: old new # ^old^new^ # # comments __END__ ^ftpmusette.cr.usgs.gov^ftpext.usgs.gov/pub/cr/co/denver/musette^