I'm trying to use sed to replace some PHP lines.

My problem is I want to replace a line with PHP variables with a string including a Bash variable.

Here is an example:

sudo sed -i 's/$sUrl . $this_sOutDir/https:\/\/'$bucketname'.s3.amazonaws.com . $this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php

As you can see, I want to replace $sUrl . $this->_sOutDir (literally) with the s3 URL, which includes a Bash variable. I'm trying to use double quotes but it's not working for me:

 sudo sed -i 's/$sUrl . $this_sOutDir/https:\/\/"$bucketname".s3.amazonaws.com . $this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php

I'm also trying to use the complete s/... in double quotes but it's not working because sed thinks that the first variables are also Bash variables.

The result is:

return https://.s3.amazonaws.com . $this->_sOutDir . '/';
  • Your example works alright for me : paste.ubuntu.com/15696070 Does bucketname contain anyting special ? is it being set ? Is it a variable with specific scope ? is it used in a function or so ? – Sergiy Kolodyazhnyy Apr 8 '16 at 19:01

You can go two different ways:

  1. Using single quotes: break out of the single quotes and reference the variable (using double quotes to prevent word splitting and filename expansion):

    sudo sed -i 's/$sUrl . $this_sOutDir/https:\/\/'"$bucketname"'.s3.amazonaws.com . $this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php
  2. Using double quotes: escape the $ characters to be treated literally:

    sudo sed -i "s/\$sUrl . \$this_sOutDir/https:\/\/$bucketname.s3.amazonaws.com . \$this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php

However, the caveat is: if $bucketname contains sed special characters / sequences, the sed command will break (in this case since the variable is to be expanded in the replacement section, the concern is about it possibly containing the separator, accidental backreferences or &.

One way to go around this is sanitazing the variable beforehand by escaping possible separators, accidental backreferences and & characters to prevent them from being interpreted as such.

Another way is using Perl instead of sed, passing the variable directly to Perl which will handle special characters at replacement time ($ characters to be treated literally must be escaped even if using single quotes with this method):

sudo perl -i -spe 's/\$sUrl . \$this_sOutDir/https:\/\/$bucketname.s3.amazonaws.com . \$this->_sOutDir/g' -- -bucketname="$bucketname"
$ echo '$sUrl . $this_sOutDir' | perl -spe 's/\$sUrl . \$this_sOutDir/https:\/\/$bucketname.s3.amazonaws.com . \$this->_sOutDir/g' -- -bucketname="string/with/separators/&/and/accidental\$1backreferences"
https://string/with/separators/&/and/accidental$1backreferences.s3.amazonaws.com . $this->_sOutDir

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.