I am trying to replace a string from a file which contains '&' in its value.

vari = '111|abc & efg|123'
varj = '222|abc & efg|123'

echo $vari | sed -e "s/$vari/$varj/g"

output is 222|abc 111|abc & efg|123 efg|123

I don't know how to handle '&' in find and replace variable. Can anyone help?

  • Just to add that i am doing this in korn shell Sep 29 '15 at 7:26

The & character in $varj has a special meaning in the replace portion of an s/search/replace/ command. It means "insert the matching text here".

You can use \& to 'escape' the & so it doesn't have a special meaning. You can use sed to modify $varj to replace all & chars with \&:

varj=$(echo "$varj" | sed -e 's/\&/\\\&/g')

For example:

cas@ganesh:/tmp$ ksh
$ vari='111|abc & efg|123'
$ varj='222|abc & efg|123'

$ echo "$vari" | sed -e "s/$vari/$varj/g"
222|abc 111|abc & efg|123 efg|123

$ varj=$(echo "$varj" | sed -e 's/\&/\\\&/g')
$ echo "$varj"
222|abc \& efg|123

$ echo "$vari" | sed -e "s/$vari/$varj/g"
222|abc & efg|123
  • super stuff. Worked Sep 29 '15 at 8:54
  • Or (with {ba,k,z}sh) simply: sed "s#${vari}#${varj//&/\\&}#g" Sep 29 '15 at 17:46

You need escape the & character in the replacement text. This is because & is a special character for the replacement text. So let your $varj be as follows.

varj = '222|abc \& efg|123'

You can then call sed as follows.

echo $vari | sed -e "s/$vari/$varj/g"
  • vari is a line from a file and i am not able to substitute anything in this line because of '&' Sep 29 '15 at 7:37
  • @girishchalke no, it is not because of the &. Just insert the \ as shown in the answer and it will work.
    – nehcsivart
    Sep 29 '15 at 7:48
  • this problem has nothing to do with spaces. even if it did, the correct way to deal with it would be to use double-quotes whenever using (e.g. echo-ing) $vari or $varj. e.g. echo "$vari" | sed .... In fact, as a general rule it is almost always best to use double-quotes around variables except in the very few instances where you know precisely why you don't want to use quotes.
    – cas
    Sep 29 '15 at 8:32
  • @tchem. Tried your recommendations but still no success. Just to ensure its not because of '&', i removed it and kept space as it is. vari="111|abc efg |123"; echo $vari |sed -e "s/$vari/$varj/g" This worked which suggests problem is with '&' Sep 29 '15 at 8:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.