mrzippy
12-29-2003, 03:28 PM
Can someone show me the correct way to do a "directory wide" search and replace for some text in certain files?
ie: I wish to replace the string "aaaaaaaa" with "bbbbbbbbb" in all files in a certain directory with the ".xyz" extension.
It can be either a series of shell commands or even a perl script.
Thanks!
RackNine
12-29-2003, 05:31 PM
Open up your shell, type:
replace -?
Should point you in the right direction.
Sincerely,
-Matt
mrzippy
12-29-2003, 05:38 PM
Originally posted by RackNine
Open up your shell, type:
replace -?
Should point you in the right direction.
Sincerely,
-Matt There is no command called "replace" in my shell.
> which replace
replace: Command not found.
:confused: Any other suggestion? :)
YUPAPA
12-29-2003, 05:53 PM
MY PERL SCRIPT!
This will replace all the .xyz files under /home/myname/mydir/ PLUS under all the dir trees under the specified dir (/home/myname/mydir/) ~ So be careful with it! You run it from SSH BTW, not browser~
#!/usr/bin/perl
use Fcntl qw(:DEFAULT :flock);
use File::Find;
use strict;
my $the_start_dir = '/home/myname/mydir/';
my %all_dirs = ();
my $text_to_look_for = 'aaaaaaaa';
my $text_to_replace = 'bbbbbbbbb';
finddepth (\&wanted, $the_start_dir);
foreach my $path (sort keys %all_dirs) {
next if($path !~ /\.xyz$/);
my $tmp_file = $path.'.'.$$;
print "Reading $path ... ";
rename($path,$tmp_file) or die "Fail to rename $path: $!\n";
sysopen(IN, $tmp_file, O_RDONLY, 0600) or die "Fail to sysopen $tmp_file for RDONLY: $!\n";
sysopen(OUT, $path, O_RDWR|O_TRUNC|O_CREAT, 0600) or die "Fail to sysopen $path for RDWR, TRUNC, CREAT: $!\n";
flock(IN, LOCK_SH) or die "Fail to SH-LOCK $tmp_file: $!\n";
flock(OUT, LOCK_UN) or die "Fail to EX-LOCK $path: $!\n";
while(<IN>) {
s/$text_to_look_for/$text_to_replace/g;
print OUT;
}
flock(IN, LOCK_UN) or die "Fail to UN-LOCK $tmp_file: $!\n";
flock(OUT, LOCK_UN) or die "Fail to UN-LOCK $path: $!\n";
close(IN) or die "Fail to close $tmp_file: $!\n";
close(OUT) or die "Fail to close $path: $!\n";
unlink($tmp_file) or die "Fail to remove tmp file $tmp_file: $!\n";
print "Done\n";
}
sub wanted {
$all_dirs{$File::Find::name}++ if (-f);
}
Steven
12-29-2003, 07:08 PM
very nice perl script yupapa.
justsurge
12-29-2003, 09:23 PM
hi, gossamer-threads.com has a sitemanager that will do what you want & has a few extra options.
Note, remove that sitemanager after using it, IMO it's a security risk.
if I may suggest?:)
this:
s/$text_to_look_for/$text_to_replace/g;
could be this:
s/\Q$text_to_look_for/$text_to_replace/g;
the \Q escapes $ . + in a regex
sub wanted {
$all_dirs{$File::Find::name}++ if (-f);
}
sub wanted {
$all_dirs{$File::Find::name}++ if (-f && -T);
}
here I added -T to only open Text files.
---------------------------------------
& it is possible to replace directory wide text using shell
using
sed -e 's/aaa/bbb/' filename
or something like this,
perl -pi -e 's/aaaaaaaaa/bbbbbbbbbbbbbb/' *html *txt *php
Ej
Slidey
12-30-2003, 11:45 AM
maybe something like
find . -name *.php -exec perl -p -i.bak -e 's/aaaaaaaa/bbbbbbbb/g' {} \;