使用 sed 的“a”命令为行添加前缀是否可移植?

使用 sed 的“a”命令为行添加前缀是否可移植?

我注意到以下有趣的行为:

$ printf '%s\n' line{1..2} | sed $'1a\\\nPREFIX'
line1
PREFIXline2
$ 

有趣的是,这种行为仅适​​用于最后的Sed 脚本中的命令,因为之后放置另一个命令需要换行符。

它也适用于插入命令:

$ printf '%s\n' line{1..2} | sed $'1i\\\nPREFIX'
PREFIXline1
line2
$ 

这种行为可以依赖吗?

我没有看到它以某种方式被提及Sed 的 POSIX 规范。它只是说text可以由一行或多行组成。 (如果一行不以换行符结尾,它仍然是一行吗?)

它还适用于多行插入:

$ printf '%s\n' line{1..2} | sed $'1a\\\n ****/\n1i\\\n/****\\\n * '
/****
* line1
****/
line2
$ 

答案1

要使用字符串作为行前缀,请使用替换 ( s) 并替换^,行首锚点:

$ printf 'line1\nline2\n' | sed '1s/^/PREFIX/'
PREFIXline1
line2

用于a在某行之后追加行,以及i在另一行之前插入一行。a和命令i并不用于修改行,而只是用于添加行。

“这个行为可以依赖吗?”不。正如 Stéphane Chazelas 在评论中指出的那样,“这显然是一个错误”,并且 GNUsed没有显示所描述的行为。


关于你的问题“如果一行不以换行符结尾,它仍然是一行吗?”,POSIX 将“线”定义为

<newline>零个或多个非字符加上终止字符的序列<newline>

所以这个问题的答案是“不,这不是一条线”。

答案2

我刚刚使用不同的 Sed 进行了测试,发现这是 BSD Sed 的一个特性; GNU Sed 给出了不同的结果,最好用上面给出的最后一个命令的输出来说明:

$ printf '%s\n' line{1..2} | sed $'1a\\\n ****/\n1i\\\n/****\\\n * '
/****
 *
line1
 ****/
line2
$

相关内容