Web Hosting Talk







View Full Version : dir-wide text search/replace?


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' {} \;