#!/usr/bin/perl
# textSubstitute.pl, textSub.pl textSu.pl
# by Meryll Larkin
return to Alwanza
# created 5/11/00 last revision: 8/22/00
# suggestions for improvement encouraged (I'm new at this)
# This perl script will:
# Substitute multiple instances of one string for another
# in files within a directory or nested directories
# provided the string does not extend beyond a single line
# It will ask for the path to the directory
# It will prompt user for error checks in multiple places
# It will allow for original text to contain regular expressions or not
# by user choice
# Make a status report for each directory &
# send the report to screen, file, or both, by user choice.
# to change revision date try regular expression, something like:
# rev\s\d+\s\w+\s\d+ this will match: rev 4 April 2000
# ********************************************************
use Cwd;
$name = ucfirst($ENV{LOGNAME});
print "\nHello $name,\n\n";
print "This script will substitute multiple instances of one string for another\n";
print "in files within a directory or nested directories.\n";
print " * provided the string does not extend over more than one line *\n";
print "You will be asked to provide:\n";
print " the path to the directory you wish to change\n";
print " the original text string(s) you wish to change\n";
print " and the new text string(s) you wish to substitute in place\n";
print " of the original text\n";
print "You will also be informed of subdirectories found nested within\n";
print "your directory, and asked if you want to make the same changes to the\n";
print "files within those directories.\n\n";
print "Do you wish to continue? (y or n)\n";
&query_continue;
&get_dirpath;
&move_into_dirpath;
&open_Dir;
&get_string_to_replace;
print "\nIn directory $dir, you are about to change the following original text:\n\n";
for ($ia = 0; $ia < $end; $ia++) {
print "$orgText[$ia] to this: $fixedText[$ia]\n";
}
print "\nDo you wish to continue? (y or n)\n";
&query_continue;
&where_report;
$subdirectToDo[0] = $dir;
chmod(0775, $dir) or die "Can't modify permissions on directory $dir: $!\n";
while ( $subdirectToDo[0] ) {
&move_into_dirpath;
&open_Dir;
if (( $statusloc eq "F") || ( $statusloc eq "B")) {
# detect & correct for existing status report
$statfile2 = "StatusReport_old.txt";
$statfile = "StatusReport.txt";
if ( -e $statfile ) {
`cp $statfile $statfile2`;
# delete statfile so new one will contain only new data.
unlink ($statfile);
}
}
# find all directory contents OTHER than those that begin and end in .
@dirContents = grep !/^\.\.?$/, readdir(CHANGEME);
# separate the files from the subdirectories
foreach $dirContent ( @dirContents ) {
#do not include StatusReports in file array for string detection
if ( $dirContent =~ /tatusRepor/) {
}
elsif (-s $dirContent) {
if (-d $dirContent) {
$subdirectFound[$#subdirectFound + 1] = $dirContent;
}
else {
$file[$#file + 1] = $dirContent;
}
}
else {
print "-s (nonzero size) test failed $dirContent\n";
}
}
if (( $statusloc eq "B") || ( $statusloc eq "F")) {
open ( STATFILE, ">>StatusReport.txt" ) or die "Can't open StatusReport.txt\n";
if ( !@file ) {
print STATFILE "No files were detected inside directory $dir\n";
}
else {
print STATFILE "The results for directory $dir:\n";
}
}
if (( $statusloc eq "B") || ( $statusloc eq "M")) {
if ( !@file ) {
print "No files were detected inside directory $dir\n";
}
else {
print "The results for directory $dir:\n";
}
}
foreach $file ( @file ) {
chmod(0775, $file) or die "Can't modify permissions on file $file: $!\n";
open(INPUT, $file) or die "Can't open $file\n";
$i = 0;
for ( $ib = 0; $ib < $end; $ib++ ) {
$boo[$ib] = "undetected";
}
while (<INPUT>) {
$html[$i] = $_; #make a line by line array of the file contents
chomp($html[$i]);
$html[$i] =~ s/\//; # delete DOS carriage return characters
$html[$i] =~ s/\r//; # delete DOS carriage return characters
for ( $ib = 0; $ib < $end; $ib++ ) {
if ( $_ =~ /$orgText[$ib]/ ) { # detect original string
$sub = $html[$i];
# substitute new string for original string
# did user indicate that string contains regular expression?
if (( $regex[$ib] ne "Y" ) && ( $regex[$ib] ne "y")) {
# the \Q and \E make this a string match and ignore regular expressions
$sub =~ s/\Q$orgText[$ib]\E/$fixedText[$ib]/;
}
else { #the default is to honor regular expressions
$sub =~ s/$orgText[$ib]/$fixedText[$ib]/;
}
$html[$i] = $sub;
$boo[$ib] = "found";
if (( $statusloc eq "B") || ( $statusloc eq "F")) {
print STATFILE "$orgText[$ib] has been detected in $file.\n";
}
if (( $statusloc eq "B") || ( $statusloc eq "M")) {
print "$orgText[$ib] has been detected in $file.\n";
}
}
}
$i++;
}
$k = $i;
for ( $ic = 0; $ic < $end; $ic++ ) {
if ( $boo[$ic] !~ "found" ) {
if (( $statusloc eq "B") || ( $statusloc eq "F")) {
print STATFILE "Unable to find $orgText[$ic] to change inside $file.\n";
}
if (( $statusloc eq "B") || ( $statusloc eq "M")) {
print "Unable to find $orgText[$ic] to change inside $file.\n";
}
}
}
#make temporary file to hold corrected data
#deconstruct file name into name and extension
if ($file =~ /\w\.\w/) {
$start = index($file, ".");
$filename = substr($file, 0, $start);
$extension = substr($file, $start);
}
# make temporary file to hold corrected data
$newfile = "$filename" . "_old" . "$extension";
# test to make sure file doesn't already exist
if ( -e $newfile ) {
$newfile = "$filename" . "_old1" . "$extension";
}
if ( -e $newfile ) {
print "Can't copy $file to $newfile because $newfile already exists.\n";
print "Quitting.\n";
exit (0);
}
open ( NEWFILE, ">>$newfile" ) or die "Can't open NEWFILE/$newfile\n";
chmod(0775, $newfile) or die "Can't modify permissions on new file $newfile: $!\n";
for ( $m = 0; $m < $k; $m++ ) {
print NEWFILE "$html[$m]\n";
}
close ( NEWFILE ); # close files before copying them!!!!!
close ( INPUT ); # close files before copying them!!!!!
#put corrected text into original filename
`cp $newfile $file`;
# delete temporary file
unlink ( $newfile );
}
shift @subdirectToDo;
# empty file array so that it will be repopulated with only files in next directory
$mend = $#file + 1;
for ( $n = 0; $n < $mend; $n++ ) {
shift @file;
}
if ( @subdirectFound ) {
if (( $statusloc eq "B") || ( $statusloc eq "F")) {
print STATFILE "\nSubdirectories were detected inside $dir:\n";
}
if (( $statusloc eq "B") || ( $statusloc eq "M")) {
print "\nSubdirectories were detected inside $dir:\n";
}
foreach $subdirectFound ( @subdirectFound ) {
if (( $statusloc eq "B") || ( $statusloc eq "F")) {
print STATFILE " $subdirectFound\n";
}
if (( $statusloc eq "B") || ( $statusloc eq "M")) {
print " $subdirectFound\n";
}
}
print "Would you like to make exactly the same changes in any of the subdirectories? (y or n)\n";
&query_moredir;
$nend = $#subdirectFound + 1;
# empty subdirfound array so that it will be repopulated with only child directories
for ( $n = 0; $n < $nend; $n++ ) {
shift @subdirectFound;
}
}
else {
if (( $statusloc eq "B") || ( $statusloc eq "F")) {
print STATFILE "No subdirectories were detected in $dir.\n\n";
}
if (( $statusloc eq "B") || ( $statusloc eq "M")) {
print "No subdirectories were detected in $dir.\n\n";
}
}
if (( $statusloc eq "B") || ( $statusloc eq "F")) {
close ( STATFILE );
}
# compile an array of completed directories for navigation purposes in subroutine
unshift (@subdirectDone, $dir);
&select_nextdir;
}
print "Job completed. Quitting.\n";
closedir ( CHANGEME );
exit (0);
#********************************************************
sub query_continue {
$continue = substr(<STDIN>, 0, 1); #take first character only
$continue =~ tr/a-z/A-Z/; #transform to upper case
if (( $continue ne "Y" ) && ( $continue ne "N" )) {
print "$continue is not a valid answer.\n";
print "Do you wish to continue? (y or n)\n";
&query_continue;
}
if ( $continue ne "Y" ) {
print "Quitting per user request.\n";
exit (0);
}
}
sub get_dirpath {
print "Write the full path to the directory that needs changes:\n";
chomp($dir = <STDIN>); #remove "enter"
if ( $dir !~ /\w/ ) {
&get_dirpath;
}
}
sub move_into_dirpath {
$dircurrent = cwd();
unless ( chdir $dir ) {
print "Can't move into $dir $!\n\n";
print "Try again, and follow this format:\n $dircurrent\n\n";
&get_dirpath;
&move_into_dirpath;
}
$dircurrent = cwd();
if ( $dircurrent ne $dir ) {
print "Is this the directory you want?\n $dircurrent\n";
$datagood = substr(<STDIN>, 0, 1); #take first character only
$datagood =~ tr/a-z/A-Z/;
if (( $datagood ne "Y") && ( $datagood ne "N")) {
print "$datagood is not a valid answer.\n";
print "Do you wish to continue? (y or n)\n";
&query_continue;
}
if ( $datagood ne "Y" ) {
&get_dirpath;
}
else {
$dir = $dircurrent;
}
}
}
sub open_Dir {
unless (opendir( CHANGEME, $dir )){
print "Can't open $dir. Do you wish to rewrite? (y or n)\n";
&query_continue;
&get_dirpath;
}
}
sub get_string_to_replace {
$datagood = "Y";
for ($is = 0; $is < 100; $is++) {
print "\nProvide one original string that you wish to change:\n";
chomp($orgText[$is] = <STDIN>); #remove "enter"
print "Does this string contain specialized characters that you wish to\n";
print "treat as \"regular expressions\"? (y or n, default = n)\n";
$regex[$is] = substr(<STDIN>, 0, 1); #take first character only
print "Provide the corrected text that you wish to substitute for $orgText[$is]:\n";
chomp($fixedText[$is] = <STDIN>); #remove "enter"
print "\nPlease confirm you want to change the following original text:\n\n";
print "$orgText[$is] to this: $fixedText[$is] in directory:\n";
print "$dir.\n\n";
print "Is this substitution correct? (y or n)\n";
$datagood = substr(<STDIN>, 0, 1); #take first character only
$datagood =~ tr/a-z/A-Z/;
if ( $datagood ne "Y" ) {
$is = $is - 1;
}
else {
print "\nWould you like to make another text substitution? (y or n)\n";
$moretext = substr(<STDIN>, 0, 1); #take first character only
$moretext =~ tr/a-z/A-Z/;
if ( $moretext ne "Y" ) {
$end = $is + 1;
$is= 100;
}
}
}
}
sub where_report {
 
print "\nWould you like to print the status report\n";
 
print "to the monitor (m), to a file (f), or both (b) ?\n";
 
$statusloc = substr(<STDIN>, 0, 1); #take first character only
 
$statusloc =~ tr/a-z/A-Z/;
 
unless (( $statusloc eq "M" ) || ( $statusloc eq "F") || ( $statusloc eq "B")) {
print "Please select m, f, or b\n";
&where_report;
}
}
sub query_moredir {
$continue = substr(<STDIN>, 0, 1); #take first character only
$continue =~ tr/a-z/A-Z/;
if (( $continue ne "Y" ) && ( $continue ne "N" )) {
print "$continue is not a valid answer.\n";
print "Would you like to make the same changes in subdirectories? (y or n)\n";
&query_moredir;
}
if ( $continue ne "N" ) {
print "Which subdirectories would you like to include?\n";
print "Write y or n after each:\n";
foreach $subdirectFound ( @subdirectFound ) {
print "\n $subdirectFound ";
$include = substr(<STDIN>, 0, 1); #take first character only
$include =~ tr/a-z/A-Z/;
if ( $include eq "Y" ) {
chmod(0775, $subdirectFound)
or die "Can't modify permissions on subdirectory $subdirectFound: $!\n";
if (( $statusloc eq "B") || ( $statusloc eq "F")) {
print STATFILE "Text will be changed in subdirectory $subdirectFound\n";
}
if (( $statusloc eq "B") || ( $statusloc eq "M")) {
print "Text will be changed in subdirectory $subdirectFound\n";
}
unshift @subdirectToDo, $subdirectFound;
}
}
}
}
sub select_nextdir {
$dir = $subdirectToDo[0];
if ( $dir ) {
print "\nThe next subdirectory selected for changes is $subdirectToDo[0]\n";
print "Shall we proceed?\n";
$dircurrent = cwd();
&query_continue;
$siend = $#subdirectDone + 1;
unless (opendir(CHANGEME, $dir)){
for ( $si = 0; $si < $siend; $si++ ) {
$old_dir = $subdirectDone[$si];
opendir( OLDDIR, $old_dir );
chdir $old_dir;
$dircurrent = cwd();
if (opendir( CHANGEME, $dir )) {
$si = $siend;
closedir ( OLDDIR );
}
else {
closedir ( OLDDIR );
}
}
}
}
}
|
|