如何在单引号和双引号下的“sed”实用程序的参数文本中插入换行符?

tao*_*iao -2 unix bash sed utility

我想使用 sed 在文件中的目标行上方插入多行。

下面file.txt包含一行“ target line”。我的初始版本使用单引号:

sed '/target line/ i\
     inserted line1;\
     inserted line2;\
     inserted line3;' file.txt
Run Code Online (Sandbox Code Playgroud)

结果是:

    inserted line1;
    inserted line2;
    inserted line3;
target line
Run Code Online (Sandbox Code Playgroud)

此版本按预期工作,每行末尾的换行符被转义为\文字换行符而不是命令终止符。请参阅此处

然后我想在替换字符串中使用 shell 变量,因此我尝试使用双引号来启用变量扩展:

sed "/target line/ i\
     inserted line1;\
     inserted line2;\
     inserted line3;" file.txt
Run Code Online (Sandbox Code Playgroud)

但这一次换行符和前四个空格消失了:

inserted line1;    inserted line2;    inserted line3;
target line
Run Code Online (Sandbox Code Playgroud)

如何在此处正确插入双引号中的换行符?

Léa*_*ris 5

带单引号

反斜杠后跟换行符按原样传输到 sed。然后 sed 实际上使用反斜杠将原始换行符转义到字符串中,而不是终止命令。看:

$ printf %s 'hello\
world' | hexdump -C
Run Code Online (Sandbox Code Playgroud)

它清楚地显示了字符串中包含的反斜杠5c后跟的换行符0a

00000000  68 65 6c 6c 6f 5c 0a 77  6f 72 6c 64              |hello\.world|
0000000c
Run Code Online (Sandbox Code Playgroud)

带双引号

反斜杠在双引号中具有特殊含义。它导致以下换行符被解释为字符串继续字符。结果是字符串中不包含反斜杠或换行符,因此 sed 看不到。

$ printf %s "hello\
world" | hexdump -C
Run Code Online (Sandbox Code Playgroud)

字符串继续,不带反斜杠和换行符:

00000000  68 65 6c 6c 6f 77 6f 72  6c 64                    |helloworld|
0000000a
Run Code Online (Sandbox Code Playgroud)

编辑

  • 准确地说,sed 实际上使用反斜杠来转义以下换行符,正如@dan 指出的那样。