file-replace.pl 2.74 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
#!/usr/bin/perl

# parse the arguments:
# file-replace [options] [--] filename[s]|dir[s]
#              --in-pattern="search for"
#              --out-pattern="replace with"
#              --in-pattern-file="file"
#              --out-pattern-file="file"
#              --no-recurse
#              --no-directories


my $search;
my $replace;
my $argflag;
my @infiles;
my $norecurse;
my $nodirs;
my$pwd=`pwd`;
chomp($pwd);

foreach $arg (@ARGV){
    if($arg eq "--"){
	$argflag=1;
	next;
    }

    if(!$argflag && $arg=~/--([^=]*)=(.*)/){
	my$key=$1;
	my$val=$2;

	if($key eq "in-pattern"){
	    $search=$val;
	    next;
	}
	if($key eq "out-pattern"){
	    $replace=$val;
	    next;
	}
	if($key eq "in-pattern-file"){
	    die "Could not open file $val: $!" unless open(F,"$val");
	    undef $/;
	    $search=<F>;
	    $/="\n";
	    close(F);
	    next;
	}
	if($key eq "out-pattern-file"){
	    die "Could not open file $val: $!" unless open(F,"$val");
	    undef $/;
	    $replace=<F>;
	    $/="\n";
	    close(F);
	    next;
	}

	print "Unknown option --$key\n";
	exit(1);
    }
    

    if(!$argflag && $arg=~/--(.*)/){
	if($key eq "no-recurse"){
	    $norecurse;
	    next;
	}
	if($key eq "no-directories"){
	    $nodirs=1;
	    next;
	}
	print "Unknown option --$key\n";
	exit(1);
    }
    
    push @infiles, ($arg);
}

&recursive_doit($pwd,@infiles);

sub recursive_doit{
    my($pwd,@globlist)=@_;
    my @dirs;
    my @files;

    # seperate files from directories
    foreach $file (@globlist){
	if(-d $file){
	    push @dirs,($file);
	    next;
	}
	if(-f $file){
	    push @files,($file);
	    next;
	}
	print "$pwd/$file is not a plain file or directory.\n";
    }

    # Are we called on a directory? recurse?
    if(!$nodirs){
        # fork into each dir with all but the original path ar
	foreach $dir (@dirs){

	    if(fork){
		wait; # don't hose the box ;-)
	    }else{
		die "Could not chdir to $pwd/$dir: $!\n" unless chdir $dir;
		$pwd.="/$dir";
		# open and read the dir
		die "Could not read directory $pwd: $!\n" unless 
		    opendir (D,".");
		#ignore dotfiles
		@globlist=grep { /^[^\.]/ && !(-l "$_") } readdir(D);
		closedir(D);
		$nodirs=$norecurse;

		recursive_doit($pwd,@globlist);
		exit(0);
	    }
	}
    }

    foreach $file (@files){
	if (open(F,$file)){
	    undef $/;
	    my$body=<F>;
	    $/="\n";
	    close(F);

	    # do the regexp
	    if($body=~s{$search}{$replace}g){

		print "Performed substitution on $pwd/$file\n";

		# replace with modified file
		my$tempfile="file-replace-tmp_$$";  
		die $! unless open(F,">$tempfile");
		syswrite F,$body;
		close(F);
		die "Unable to replace modified file $file: $!\n" unless 
		    rename($tempfile,$file);
		unlink $tempfile;
	    }

	}else{
	    print "Could not open $pwd/$file: $!\n";
	}
    }
    exit(0);
}