dumb multi-file find and replace

puts “Done.”


Mike suggested rpl, below, and it seems good. This makes our script:

#!/usr/bin/env ruby
puts "Not enough args" or exit unless (A = ARGV)[1]
A.map!{|s| s.inspect[1..-2]}
formats = [".rhtml", ".rb", ".yml", ".rjs", "Rakefile"]
formats.map!{|s| " -x'#{s}'"}
system "rpl -Re #{formats} '#{A[0]}' '#{A[1]}' #{A[2] or '*'}"

I’m still using Ruby as a wrapper; it’s easiest.

4 responses

  1. How about this, for a non-recursive solution?

    perl -pi -e 's/find/replace/g' \
      *.rhtml *.rb *.yml *.rjs

    Or recursively,

    find -E . -regex '.**\.(rhtml|rb|yml|rjs)' \
      | xargs perl -pi -e 's/find/replace/g'

    Then, turn it into a shell function that accepts the find and replace bits as arguments.

  2. I see a pipe! It’s a big improvement over the sed/mv combo, though, which clobbers the executable bit.

    Recursive is key. And I don’t know how to Regexp-escape parameters in a Bash function, but there must be a way.

    Can we get it smaller yet? If there is something I can install out of Ports or APT, that’s fair game.

  3. rpl – intelligent recursive search/replace utility

    sudo apt-get -uf install rpl

    Just FYI, GNU sed has an inplace edit argument (-i[SUFFIX] / --in-place[=SUFFIX]) too, SUFFIX being the suffix to append to the original file (some sed builds seem to require this others seem to accept it optionally).

  4. Looks like rpl is the winner:

    rpl -R -x'.rb' -x'.rhtml' -x'.yml' -x'.rjs' from to *

    It’s nice that it reports how many replacements it made.