Friday, April 8, 2011

sed scripting - environment variable substitution

Hi all,

I have sed related question:

If I run these command from a scrip:

#my.sh
PWD=bla
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
xxx
bla

Which is fine.

But, if i run:

#my.sh
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
$ sed: -e expression #1, char 8: Unknown option to `s'

I read in tutorials that to substitute env. variables from shell you need to stop, and 'out quote' the $varname part so that it is not substituted directly, which is what I did, and which works only if the variable is defined immediately before.

How can I get sed to recognize a $var as a env. variable as it is defined in the shell ?

From stackoverflow
  • With your question edit, I see your problem. Let's say the current directory is /home/yourname ... in this case, your command below:

    sed 's/xxx/'$PWD'/'
    

    will be expanded to

    sed `s/xxx//home/yourname//
    

    which is not valid. You need to put a \ character in front of each / in your $PWD if you want to do this.

    Roman M : but PWD is defined by the shell ... if i go echo $PWD i get the pwd
  • Your two examples look identical, whcih makes problems hard to diagnose. Potential problems:

    1. You may need double quotes, as in sed 's/xxx/'"$PWD"'/'

    2. $PWD may contain a slash, in which case you need to find a character not contained in $PWD to use as a delimiter.

    Roman M : tnx Norman, 2. Was the problem ... I didn't realize im using '/' as the pattern deliminator and as part of the substitution string ... solved ...
    Roman M : but, then what character can i use i know for sure will not appear in a path name ?
    Norman Ramsey : You can have several candidates like @#%! and check with a case expression to find if $PWD has them. E.g., case "$PWD" of *@*) ;; *) delim="@" ;; esac; repeat until $delim is not empty.
  • In addition to Norman Ramsey's answer, I'd like to add that you can double-quote the entire string (which may make the statement more readable and less error prone).

    So if you want to search for 'foo' and replace it with the content of $BAR, you can enclose the sed command in double-quotes.

    sed 's/foo/$BAR/g'
    sed "s/foo/$BAR/g"
    

    In the first, $BAR will not expand correctly while in the second $BAR will expand correctly.

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.