2

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 ?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
wizzup
  • 2,361
  • 20
  • 34

2 Answers2

1

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.

janos
  • 120,954
  • 29
  • 226
  • 236
  • More robustly is to always use `sed 's/%VERSION%/'"$(date)"'/'` so you only expose the part of the script to the shell that you want exposed and so don't have to worry about `$`, for example, appearing in the other parts. – Ed Morton Dec 02 '17 at 14:22
1

Use double-quotes to do the substitution and avoid using the outdated `` construct but rather use the $(..) syntax for Command substitution

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

Also another way if you just want to use the single quotes, would be to wrap the substitution part in double-quotes and then single-quote on top of it, something like sed 's/%VERSION%/'"$(date)"'/' file which is less efficient than simply double-quoting the entire substitution string.

Inian
  • 80,270
  • 14
  • 142
  • 161