in reply to One-line shell script for find and replace

One way to do it, assuming you have find available:
perl -pi -w -e 's/find/replace/g' `find ./ -name *.txt`

Replies are listed 'Best First'.
Re^2: One-line shell script for find and replace
by Skeeve (Parson) on Oct 05, 2005 at 07:53 UTC
    1. No need for the / after the .
    2. 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

      I still prefer:

      find . -name '*.txt' -exec perl -pi -e 's/find/replace/g' {} \;
      daniel
        In the prior solution, you execute the perl interpreter once. In yours, you execute it many times. You gain maybe a little clarity, but you lose on performance. Only pointing this out if you have 10k files to deal w/
Re^2: One-line shell script for find and replace
by blazar (Canon) on Oct 05, 2005 at 08:10 UTC
    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.
Re^2: One-line shell script for find and replace
by Anonymous Monk on Oct 05, 2005 at 23:00 UTC
    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 <>} +,".")'

      Close, but you can do better.

      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.