sed行号特定替换使用g选项和here-string更改每个模式

问题描述

在使用管道时,无论是否使用全局 g 选项,都会产生相同的结果:

echo -e 'hi\nhello\nhi' | sed '1s/hi/hey/g'
hey
hello
hi
当不使用全局 g 选项时,

也适用于此处字符串

sed '1s/hi/hey/' <<< $(echo -e 'hi\nhello\nhi')
hey hello hi

但是使用全局 g 选项和 here-string 会替换每行的模式:

sed '1s/hi/hey/g' <<< $(echo -e 'hi\nhello\nhi')
hey hello hey

为什么在使用全局替换标志并且输入通过here-string时输出发生这种变化?

解决方法

sed脚本关系不大,并且与bash此处的字符串表示法和引号有很大关系。使用cat代替sed,您会看到:

$ echo -e 'hi\nhello\nhi' | cat
hi
hello
hi
$ cat <<< $(echo -e 'hi\nhello\nhi')
hi hello hi
$ cat <<< "$(echo -e 'hi\nhello\nhi')"
hi
hello
hi
$

因此,您可以看到,使用不带引号的here-string,您在一行上得到三个单词。 g命令sed上的1s/hi/hey/g修饰符意味着在输入的第一行出现的hi都被更改了。在没有g修饰符的情况下,仅更改第一行上的第一个匹配项。第三行永远都不会被修改,因为1中的1s/hi/hey/将更改限制在输入的第一行。

这也说明了3行与1行输出。