3
$ echo 'output: " ' | sed "s/\"/\"/"
output: "

$ echo 'output: " ' | sed "s/\"/\\\"/"
output: "

$ echo 'output: " ' | sed "s/\"/\\\\\"/"
output: \"

I want to understand what is happening in the first and second example. What I understand is, since I am using double quotes for the sed expression, \" is interpreded as " and \\ is interpreted as \. If so then why is my second output comming out to be " instead of \"?

I know I could have used single quotes in sed as 's/"/\"/' and it doesn't works as inteded and replaces " with ".

I am really curious why this behaviour is observed for double quotes.

  • GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu)
  • sed (GNU sed) 4.8
2
  • 1
    You say 's/"/\"/' works? It shouldn't. You would need \\" in the replacement text.
    – Kusalananda
    Jan 6, 2021 at 12:52
  • oh yes thats a mistake, thanks for pointing it out
    – pi-star
    Jan 6, 2021 at 13:12

1 Answer 1

6

In the shell specification:

2.2.3 Double-Quotes

Enclosing characters in double-quotes ( "" ) shall preserve the literal value of all characters within the double-quotes, with the exception of the characters backquote, dollar-sign, and backslash, as follows:

(...)

The backslash shall retain its special meaning as an escape character only when followed by one of the following characters when considered special:
$ ` " \ <newline>

Therefore,

Case Before shell (what you see) After shell (what Sed gets)
1 "s/\"/\"/" s/"/"/
2 "s/\"/\\\"/" s/"/\"/
3 "s/\"/\\\\\"/" s/"/\\"/

In Sed's specification, s command:

The meaning of an unescaped backslash immediately followed by any character other than '&', backslash, a digit, newline, or the delimiter character used for this command, is unspecified.

So in case 2 the output is unspecified (i.e., Sed implementations are free to interpret such cases as they like). GNU Sed took that freedom to offer several special characters, among which \r for carriage return, \n for newline, etc. (see the complete list in the manual). \" is not one of them and it chooses to simply remove the backslash. As a result, case 2 becomes equivalent to case 1 in GNU Sed.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .