:
: Hi. I have my home directory changed to another place (Original :/users/pk1/original & Now:/users/pk2/current). After copying all my files to the new home_DIR, I want to replace all the '/users/pk1/original' with '/users/pk2/current' in all of my files so that my settings would be correct.
The easiest thing is to use sed
for file in *; do
sed "s,$olddir,$newdir,g" < $file > $file.$$ && mv $file.$$ $file
done
But that runs into problems if the old or new dirs contain commas.
It also fails on binary files. You probably also wanted to keep
a copy of the old version around.
Here's a pretty complete solution I once devised for this problem. This
includes the part to copy all the files from one place to another (using
tar), and then change all the strings internally in those files, even in
the binary ones!
--tom
#!/usr/bin/perl
$BS = 8;
require 'getopts.pl';
sub usage {
die "usage: $0 [-b] [-s srcdirname] [-d dstdirname] srcdir dstdir\n";
Quote:}
&Getopts('bs:d:') || &usage;
die "srcdir $srcdir not a directory\nBailing out" unless -d $srcdir;
if (!-e $dstdir) {
mkdir($dstdir, 0777) || die "cannot mkdir $dstdir: $!" ;
Quote:}
die "dstdir $dstdir not a directory\nBailing out" unless -d $dstdir;
$olddir = $opt_s || $srcdir;
$newdir = $opt_d || $dstdir;
if (($binaries_too = $opt_b) && length($newdir) > length($olddir)) {
warn "$0: newdir longer than olddir, will only munge text files\n";
$binaries_too = 0;
Quote:}
$pad = "\0" x (length($olddir) - length($newdir)) if $binaries_too;
print <<EOF;
Changing all instances $olddir to $newdir in files
copied from "$srcdir"
to "$dstdir".
EOF
open(FILES, "(cd '$srcdir'; tar cbf ${BS} - .) |
(cd '$dstdir'; tar xpvBbf ${BS} -) |") ||
die "can't create double tar pipe";
while (<FILES>) {
next unless /^x \.\/(.*), \d+ bytes/;
$files++;
$name = "$dstdir/$1";
next unless -f $name && -s _ &&
(($ascii = -T _) || $binaries_too);
unless (open(FILE, "< $name")) {
warn "can't open $tmp: $!";
next;
}
$tmp = &maketmp($name);
unless (open (TMP, ">$tmp")) {
warn "can't create $tmp: $!";
next;
}
$changed = 0;
while (<FILE>) {
$changed += $ascii
? s/$olddir/$newdir/go
: s/$olddir([^\0]*\0)/$newdir${1}$pad/go;
if (!print TMP) {
warn "error writing to $tmp: $!";
unlink $tmp;
next;
}
}
close TMP;
if (! $changed) {
unlink $tmp;
next;
}
if (!rename($name, "$name.ORIG")) {
warn "couldn't rename $name to $name.ORIG: $!";
next;
}
if (!rename($tmp, $name)) {
warn "couldn't rename $tmp to $name: $!";
next;;
}
print "$name\n";
$updates++;
$bupdates++ unless $ascii;
Quote:}
close FILES;
warn "\ntar pipe exited $?!\n" if $? >>= 8;
printf "\n%d %s copied", &plural($files, "file");
printf ", %d of which %s updated", &plural($updates, "was")
if $updates;
printf " (%d %s)", &plural($bupdates, "binary") if $bupdates;
print ".\n";
sub maketmp {
local($fname) = shift;
$fname .= ".$$.aaa";
$fname++ while -e $fname;
$fname;
Quote:}
# ok, so i'm silly
sub plural {
if ($n != 1) {
if ($_ eq 'was') {
$_ = 'were';
} else {
s/y$/ies/ || s/s$/ses/ || s/([cs]h)$/$1es/ ||
s/sis$/ses/ || s/ium$/ia/ || s/$/s/;
}
}
return ($n, $_);
Quote:}
__END__
--
Man is the best computer we can put aboard a spacecraft ... and the
only one that can be mass produced with unskilled labor.
-- Wernher von Braun