Search code examples
bashsedquoting

How to use backtick command result with sed?


I want to replace the version in my code using git rev-parse HEAD with template string %VERSION% in a source file.

For simplicity I will use date as version command in this question.

Given test.txt

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

Expect

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

These are failed try

$ 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-%.

Do I really need to use xargs ?


Solution

  • You can embed $(...) within double-quotes, but not in single-quotes:

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

    (Same as `...` but you shouldn't use that obsolete syntax, $(...) is better.)


    Btw, for testing purposes, it's better to use sed without -i, so the original file is not modified:

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

    As a side note, and this is a completely different discussion, but worth mentioning here. This may look like it should work but it doesn't, and you may wonder why:

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

    Why it doesn't work? Because the $DD embedded in the "..." is evaluated at the time the command is executed. At that time the value of DD is not set to the output of $(date). In the "..." it will have whatever value it had before executing the command. For the sed process, the value DD with the output of $(date) is visible, but sed doesn't use that, because why would it. The "..." passed to sed is evaluated by the shell, not by sed.