[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bash script - pass command line arg to embedded sed script with multiple args



Daniel D Jones <ddjones@riddlemaster.org> wrote:
> What I want to do is call a bash script with a couple of arguments, and,
> within the script, call sed to use those args to replace two
> placeholders in a file:

> bashscript SUB1 SUB2

> This line inside bashscript doesn't work:
> sed -e 's/PLACEHOLDER1/$1/' -e 's/PLACEHOLDER2/$2/' < input > output

Single quotes tells the shell to use the contents verbatim. Double quotes
allows the shell to interpolate variables. Note that sed does not get
to see the quotes at all (see below).

> It doesn't work because the command line args ($1, $2) are quoted and don't 
> get replaced.

Yes...


> However, because I'm using the -e argument to sed, I have to 
> quote the argument or sed gets all huffy.

This is a red herring. The -e argument allows you to introduce multiple
operations. Omit it and you get just a single shot (as you
demonstrate). Sed doesn't see the quotation marks at all, so you're
slightly on the wrong track with your reasoning.


> The only workaround I've found is to do the substitutions in two passes:

> sed s/SUB1/$1/ < input > temp 
> sed s/SUB2/$2/ < temp > output

Which is almost exactly the same as this:

    sed "s/SUB1/$1/" < input > temp 
    sed "s/SUB2/$2/" < temp > output

*except* that in my case the $1 and $2 can contain whitespace, but in
yours they can't. (In neither case can they contain "/".)


> Since I'm not using multiple argument to sed, I don't have to quote
> the arg.

As explained above, this is incorrect.


> I suppose I could pipe one sed command to another rather than using
> a temp file but that's not significantly more palatable.

Given the knowledge constraints under which you're working, I'm curious
to understand why you prefer a temporary file to a pipe.


> Any ideas on a cleaner approach on how to do this, either by getting this 
> right or using an alternative method, are welcome [...]

    sed -e "s/PLACEHOLDER1/$1/" -e "s/PLACEHOLDER2/$2/" <input >output

    perl -pe 'BEGIN {($a,$b)=splice(@ARGV,0,2)} s/PLACEHOLDER1/$a/;s/PLACEHOLDER2/$b/' "$1" "$2" <input >output

The potential advantage of the perl version is that the variable can
contain not only whitespace but also "/" characters. I don't know if
this is an issue.

Chris


Reply to: