如何在 sed 中使用反引号命令结果?

How to use backtick command result with sed?

我想用源文件中的模板字符串 %VERSION% 替换代码中使用 git rev-parse HEAD 的版本。

为了简单起见,我将在这个问题中使用 date 作为版本命令。

给定 test.txt

$ echo "This is test-%VERSION%." > test.txt
$ cat test.txt
This is test-%VERSION%.

期待

This is test-Sat Dec  2 16:48:59 +07 2017.

这些都是失败的尝试

$ echo "This is test-%VERSION%." > test.txt
$ sed -i 's/%VERSION/`date`/' test.txt && cat test.txt
This is test-`date`%.

$ echo "This is test-%VERSION%." > test.txt
$ DD=`date` sed -i 's/%VERSION/$DD/' test.txt && cat test.txt
This is test-$DD%.

$ echo "This is test-%VERSION%." > test.txt
$ DD=`date` sed -i "s/%VERSION/$DD/" test.txt && cat test.txt
This is test-%.

我真的需要使用 xargs 吗?

您可以将 $(...) 嵌入双引号中,但不能嵌入单引号中:

sed -i "s/%VERSION%/$(date)/" test.txt && cat test.txt

(与 `...` 相同,但您不应使用过时的语法,$(...) 更好。)


顺便说一句,出于测试目的,最好使用 sed 而不使用 -i, 所以原始文件没有被修改:

sed "s/%VERSION%/$(date)/" test.txt

作为旁注,这是一个完全不同的讨论, 但在这里值得一提。 这可能看起来应该有效但实际上无效,您可能想知道为什么:

DD=$(date) sed -i "s/%VERSION%/$DD/" test.txt && cat test.txt

为什么不起作用? 因为嵌入在 "..." 中的 $DD 是在执行命令时计算的。 那时DD的值是不是设置到$(date)的输出。 在 "..." 中,它将具有执行命令之前的任何值。 对于 sed 过程,输出 $(date) 的值 DD 是可见的, 但是 sed 不使用它,因为为什么要使用它。 传递给 sed"..." 由 shell 计算,而不是 sed.

使用双引号进行替换并避免使用过时的 `` 结构,而是使用 $(..) syntax for Command substitution

sed -i "s/%VERSION%/$(date)/" file

还有另一种方法,如果你只想使用单引号,将替换部分用双引号括起来,然后在它上面加上单引号,比如 sed 's/%VERSION%/'"$(date)"'/' file 这样效率较低而不是简单地双引号整个替换字符串。