Re: One-line shell script for find and replace
by mrkoffee (Scribe) on Oct 05, 2005 at 07:47 UTC
|
One way to do it, assuming you have find available:
perl -pi -w -e 's/find/replace/g' `find ./ -name *.txt`
| [reply] [d/l] [select] |
|
- No need for the / after the .
- You forgot to put a \ in front of *
If you don't put it there your find will fail as soon as you have *.txt files in the current directory because the shell will replace "*.txt" by a list of those files.
So:
perl -pi -w -e 's/find/replace/g' `find . -name \*.txt`
OTOH: I prefer to use xargs for situations like this, just because the command line usually has limits.
find . -name \*.txt -print0 | xargs -0 perl -pi -w -e 's/find/replace/
+g'
$\=~s;s*.*;q^|D9JYJ^^qq^\//\\\///^;ex;print
| [reply] [d/l] [select] |
|
find . -name '*.txt' -exec perl -pi -e 's/find/replace/g' {} \;
| [reply] [d/l] |
|
|
Oh, and in addition to Skeeve's comments, I don't really like the backtics, be it in Perl or in shell. So I generally stick with qx/.../ and $() respectively, although I'm not really sure whether the latter is portable. For sure it does work in bash, and has the added benefit that it's nestable.
| [reply] [d/l] [select] |
|
There's a chance here of the combined list of files overrunning the shell command line buffer.
perl -MFile::Find -i -e 'find(sub{@ARGV=($_);s/find/replace/ while <>}
+,".")'
| [reply] [d/l] |
|
perl -MFile::Find -pi -e'BEGIN { find( sub { push @ARGV, $File::Find::
+name if /\.txt\z/i }, "." ) } s/find/replace/'
With File::Find::Rule you write it more nicely.
perl -MFile::Find::Rule -pi -e'BEGIN { @ARGV = File::Find::Rule->name(
+ "*.txt" )->in( "." ) } s/find/replace/'
But in practice I’d use find -print0 | xargs -0 for this. Way too much work to do it in Perl.
Makeshifts last the longest. | [reply] [d/l] [select] |
Re: One-line shell script for find and replace
by EvanCarroll (Chaplain) on Oct 05, 2005 at 07:48 UTC
|
| [reply] [d/l] |
|
| [reply] [d/l] |
|
| [reply] [d/l] [select] |
|
|
Re: One-line shell script for find and replace
by Moron (Curate) on Oct 05, 2005 at 10:51 UTC
|
When addressing certain facts; that the OP did not specify what OS they are running (could be windoze, VMS or mac); that, even if it is unix or linux, files in hidden directories or called .anything.txt should probably be left alone (I believe files beginning with '~' for windows, although I don't do much windows) and also that for example find -print0 works on linux but not unix; a short script instead of a one liner would become necessary, perhaps this: # a unix/linux version:
Traverse('./');
sub Traverse{
my $dir = shift;
opendir my $dh, $dir or die "$!, for $dir";
for my $file ( grep !/^\./, readdir $dir ) { # but adjust for OS
my $path = "$dir/$file";
if ( -d $path ) {
Traverse( $path );
}
else {
( $file =~ /\.txt$/ ) and Process( $path );
# or for VMS /\.TXT\;\d+$/
}
}
closedir $dh;
}
sub Process{
my $file = shift;
open my $fh "<$file" or die "$!, for $file";
my @updated = ();
while( <$fh> ) {
s/find/replace/g;
push @updated;
}
close $fh;
open $fh, ">$file" or die "$!, for $file";
print $fh @updated;
close $fh;
}
| [reply] [d/l] |
Re: One-line shell script for find and replace
by PodMaster (Abbot) on Oct 05, 2005 at 07:50 UTC
|
perl -pi -w -e 's/find/replace/g;' subdirectory/*.txt
??
MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!" | I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README). | ** The third rule of perl club is a statement of fact: pod is sexy. |
| [reply] [d/l] |
|
| [reply] [d/l] [select] |
|
Eg:
1. home/xyz.txt
2. home/contacts/abc.txt
3. home/contacts/addresses/pqr.txt
Within the 'home' directory I need to find and replace a particular word in all text files (xyz.txt, abc.txt, pqr.txt)
| [reply] |
|