I am trying to execute the following command from bash shell:

sed -i "s/\(update.*\)where /\1 where primary_id = '$primary_id', /" *.php

As you see, there is a variable which I am inserting using sed -- i.e. '$primary_id'. After executing the command, I see that the ''s are displayed, however $primary_id is missing.

How can I handle special characters, such as '?

  • 2
    Where's the output? – voices Jan 4 '16 at 7:30
  • Those quote marks are being included because that's what your sed command has been instructed to do. Has $primary_id been given a value at the point the sed is run? Or are you wanting the literal '$primary_id' to be inserted into your PHP files? Please edit your question to make this clear. – roaima Jan 4 '16 at 10:29
  • What is unclear about this question? It is precisely the issue I face, and I understood the OP as it is currently written/edited. I do not think it should be closed. I don't have the Cast Close And Reopen Votes privs as I do on stackoverflow to vote to reopen here on stackexchange. – broc.seib Sep 1 '17 at 2:07

Let's make this a bit simpler. You want to replace every occurence of a with '$b' (a dollar, a b enclosed in single quotes). c, what the variable $b happens expands to, is not what you want.

sed -i "s/a/'$b'/g" *.php

The above command is similar to what you are doing in your problem. Because the string s/a/'$b'/g is enclosed in double quotes, variables are expanded, and the replacement string is 'c'.

If the whole sed command is enclosed in double quotes, you need to escape $. This is one solution:

sed -i "s/a/'\$b'/g" *.php\

Another possibility is to quote nothing, except for any character that has a spedcial meaning to the shell (not recommended, but it might be insightful):

sed -i s/a/\'\$b\'/g *.php
| improve this answer | |
  • Why the downvote? It's a perfectly reasonable assumption of requirements from the unclear question, and clearly explains those assumptions up front. +1 from me – roaima Jan 4 '16 at 10:30
  • 1
    @roaima, it could be because of the sed -i 's/a/\'$b\'/g' *.php one which would only work with the fish shell. – Stéphane Chazelas Jan 4 '16 at 10:37
  • @StéphaneChazelas possibly, but references to fish and zsh are not at all uncommon on U&L (although they are generally flagged up explicitly so people don't assume they're bash code) – roaima Jan 4 '16 at 10:41
  • Assumptions, assumptions, assumptions. Thanks, @StéphaneChazelas, removed! – joepd Jan 4 '16 at 10:42
  • The last thing makes no sense. quote nothing except for any character that has a special meaning to the shell is all you ever can quote with shell quotes anyway. what do you think you're doing when you quote shell commands? sed "s/a/'$"b\'/g also works. – mikeserv Jan 8 '16 at 17:34

Unless I misunderstand, your command works exactly as expected:

$ cat test_file 
update name where a='b'
$ export primary_id="test"
$ sed -i "s/\(update.*\)where /\1 where primary_id = '$primary_id', /" test_file
$ cat test_file 
update name  where primary_id = 'test', a='b'
| improve this answer | |

Special characters, preceded by \'s will be taken literally.
(Like you've done with your parentheses: (\( \))).

It should look like this: \'.
If you find that still doesnt work try: '\''.
Alternatively, try the hexadecimal escape sequence: \x27.

Also, regarding sed: Enclose your expression with:
Single Quotes ('s/1/2/g'). Not Doubles ("s/1/2/g").

sed -i 's/\(update.\*\)where /\1 where primary_id = \'$primary_id\', /' \*.php  

sed -i 's/\(update.\*\)where /\1 where primary_id = '\''$primary_id'\'', /' \*.php

sed -i 's/\(update.\*\)where /\1 where primary_id = \x27$primary_id\x27, /' \*.php
| improve this answer | |
  • Why was this voted down? It's correct. – voices Jan 4 '16 at 12:27
  • then why did you edit it? it's still basically incorrect even now, even it isn't just syntax error as before. ' is not a special character to sed - but is to the invoking shell. – mikeserv Jan 4 '16 at 15:08

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