Home > database >  How do single and double quotes affect the behavior of the newline in replacement string in Linux &q
How do single and double quotes affect the behavior of the newline in replacement string in Linux &q

Time:06-29

I'd like to insert multiple lines in a file by using sed.

The file.txt below contains one line "target line". My initial version is:

sed '/target line/ i\
     inserted line1;\
     inserted line2;\
     inserted line3;' file.txt

This version works as expected that the newline is escaped by "\" at the end of the line. Refer to enter image description here

Then I'd like to use shell variable in the replacement string, so I tried to use double quotes to enable the variable expansion:

sed "/target line/ i\
     inserted line1;\
     inserted line2;\
     inserted line3;" file.txt

But this time the newline and the first four spaces disappeared. enter image description here

After some trial and error, I found this version works with double quotes:

sed "/target line/ i\
\     inserted line1;\n\
     inserted line2;\n\
     inserted line3;" file.txt

enter image description here

This behavior confuses me. What is the mechanism under the hood here?

CodePudding user response:

With single-quotes:

The backslash followed by the newline are transmitted as-is to sed. Although, sed just ignores the backslash. See:

$ printf %s 'hello\
world' | hexdump -C

Which clearly shows the backslash 5c followed by the newline 0a contained in the string.

00000000  68 65 6c 6c 6f 5c 0a 77  6f 72 6c 64              |hello\.world|
0000000c

With double-quotes:

The backslash has special meaning in double-quotes. It causes the following newline character to be interpreted as a string continuation character. The consequence is that neither the backslash or the newline are contained in the string and so not seen by sed.

$ printf %s "hello\
world" | hexdump -C

The string is continued without backslash and without newline:

00000000  68 65 6c 6c 6f 77 6f 72  6c 64                    |helloworld|
0000000a

CodePudding user response:

In double quotes, backslash escapes these characters (only):

$`"\

and newline character. So eg echo "\$" prints $.

To preserve the backslash in double quotes, escape it with another backslash:

 sed "/target line/ i\\
     inserted line1;\\
     inserted line2;\\
     inserted line3;" file.txt
  • Related