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

时间:2017-12-02 09:52:36

标签: bash sed quoting

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

为简单起见,我将在此问题中使用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吗?

2 个答案:

答案 0 :(得分:1)

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

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流程,输出为DD的值$(date)可见, 但是sed没有使用它,因为它为什么会这样。 传递给"..."的{​​{1}}由shell评估,而不是sed评估。

答案 1 :(得分:1)

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

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

另一种方法,如果你只想使用单引号,将替换部分用双引号括起来,然后在它上面单引号,类似于sed 's/%VERSION%/'"$(date)"'/' file,效率低于简单双引号整个替换字符串。