sed 行号特定替换改变了使用 g 选项和此处字符串的每个模式

sed line number specific substitution changes every pattern on using g option and here-string

当使用带或不带全局 g 选项的 pipe 时,结果相同:

echo -e 'hi\nhello\nhi' | sed '1s/hi/hey/g'
hey
hello
hi

在不使用全局 g 选项时也适用于 here-string

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 here-string 符号和引号有很大关系。使用 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,您可以在一行中得到三个词。 sed 命令 1s/hi/hey/g 上的 g 修饰符表示输入第一行出现的两个 hi 都已更改。在没有 g 修饰符的情况下,仅更改第一行中的第一个匹配项。第三行永远不会被修改,因为 1s/hi/hey/ 中的 1 将更改限制在输入的第一行。

这也解释了 3 行 vs 1 行输出。