Problems passing shell arguments to perl

Semi-newbie, so flame throwers to 'singe-only', please. :wink:

I have a large number of (say) .html files, where I'd like to do a recursive in-place search and replace a particular string. The following bit of perl works fine:

perl -pi -e 's/oldstring/newstring/g' `find ./ -name *.html`

But, I can never remember the specific commends (getting old), so I generally dump this sort of thing into a script. Say, a bash script. But, I'm having a heck of a time getting the script to take command line args and pass them to the perl script. Imagine said script is called replace_string

Suppose I want to change the occurrence of 2013 to 2014. What I want to be able to do is type

> replace_string 2013 2014

So in my bash script, I've tried the following:

#!/bin/bash
echo "target string -- $1"
echo "new string -- $2"
perl -pi -e 's/$1/$2/g' `find ./ -name *.html`

But, this doesn't work. I've tried putting double-quotes around $1 and $2, but..nada.

I'm guessing this is a simple no-brainer sort of thing, but I haven't sussed it out yet. Pointers to the obvious appreciated.

(Note: I've no doubt there are other ways to do the inplace search and replace, but that isn't the point here -- the problem is general -- passing bash shell comand args to a perl function)

Your shell variables should appear in double quotes outside of single quotes. In this simple case you can do

perl -pi -e "s/$1/$2/g" `find ./ -name *.html`

More complex perl code should be in single quotes, but ending around the shell variables as follows:

perl 'print $perlvar,"'"$shellvar"'",$perlvar;'

The shell sees 3 strings and does variable substitution in the middle string because it is in double quotes.
--
This won't work if the file names have space characters, or can result in 'too many arguments' if there are many files.
Safer is

find ./ -name *.html -exec perl -pi -e "s/$1/$2/g" {} +
1 Like

Perfect. In spaces in my file names, but the occasional hyphen (I know, I should *never* use hyphens, but...)

Thanks very much for the clear and thorough response.