首页 > 解决方案 > SED 的替换字符串被认为是单行字符串,而它包含换行符

问题描述

我正在测试sed命令以用 3 行替换一行,然后删除最后一行。(我本可以只用前 2 行代替它,但这是故意这样表述的,以展示主要问题)。

假设我有以下文字:

// ##OPTION_NAME: xxxx

我想用 2 个新行替换令牌并将其##OPTION_NAME包围##OP-NAME;像这样:

// ##OP-START
// ##OP-NAME: xxxx
// ##OP-END

为了说明这一点,我将此文本放在code.c文件中,并将 sed 命令放在名为script.sed的 sed 脚本中。
然后,我调用以下 shell 命令:

外壳命令

sed -f script.sed code.c

脚本.sed

# Begin by replacing patterns by their equivalents, surrounding them with ##OP-START and ##OP-END lines
s/\(.*\)##OPTION_NAME:\(.*\)/\1##OP-START\n\1##OP-NAME:\2\n\1##OP-END/g

问题

现在,我在 script.sed 中添加另一个 sed 命令来删除包含##OP-END. 惊喜 !所有 3 行都被删除了!

# Begin by replacing patterns by their equivalents, surrounding them with ##OP-START and ##OP-END lines
s/\(.*\)##OPTION_NAME:\(.*\)/\1##OP-START\n\1##OP-NAME:\2\n\1##OP-END/g

# Last parse; delete ##OP-END
/##OP-END/d

我试过\r\n而不是\n在替换命令 s/\(.*\)##OPTION_NAME:\(.*\)/\1##OP-START\n\1##OP-NAME:\2\n\1##OP-END/g中,但它不起作用。

我还测试了##OP-START它是否有一些不同,但是唉!所有 3 行也被删除。

似乎 sed 将其视为一条线!

标签: bashshellsed

解决方案


这并不奇怪,d模式空间上运行,而不是在每行的基础上。使用命令修改后s,您的模式空间包含 3 行。它的内容与表达式匹配,因此被删除。

要从模式空间中删除这一行,您需要s再次使用该命令:

s/\(.*\)##OPTION_NAME:\(.*\)/\1##OP-START\n\1##OP-NAME:\2\n\1##OP-END/g$
s/\n\/\/ ##OP-END//

关于模式保持空间:https ://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html#tag_20_116_13


推荐阅读