38

I have a file that contains:

<?php return 0;

I want to replace in bash, the value 0 by the current timestamp.

I know I can get the current timestamp with:

date +%s

And I can replace strings with sed:

sed 's/old/new/g' input.txt > output.txt

But how to combine the two to achieve what I want? Solutions not involving sed and date are welcome as well, as long as they only use shell tools.

BenMorel
  • 34,448
  • 50
  • 182
  • 322

2 Answers2

54

In general, do use this syntax:

sed "s/<expression>/$(command)/" file

This will look for <expression> and replace it with the output of command.


For your specific problem, you can use the following:

sed "s/0/$(date +%s)/g" input.txt > output.txt

This replaces any 0 present in the file with the output of the command date +%s. Note you need to use double quotes to make the command in $() be interpreted. Otherwise, you would get a literal $(date +%s).

If you want the file to be updated automatically, add -i to the sed command: sed -i "s/.... This is called in-place editing.


Test

Given a file with this content:

<?php return 0;

Let's see what it returns:

$ sed "s/0/$(date +%s)/g" file
<?php return 1372175125;
Graham
  • 7,431
  • 18
  • 59
  • 84
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • Oh, you just wanted to change `0`, not the whole ` – fedorqui Jun 25 '13 at 15:53
  • 1
    I have taken the liberty to update your answer to reflect my exact use case :-) Not sure why someone downvoted you without a comment, by the way. – BenMorel Jun 25 '13 at 16:52
  • Yeah, I didn't understand that downvote... Anyway, good point editing with the exact use case, @Benjamin! Regards – fedorqui Jun 26 '13 at 09:24
  • 6
    How would one make this work if the command had to be invoked every time there is a match ? – Jean-Michaël Celerier Sep 03 '17 at 12:46
  • @Jean-MichaëlCelerier I believe exactly like I am showing in my answer. I would need more details! – fedorqui Sep 04 '17 at 06:58
  • 1
    No, in your answer the command `"$(date +%s)"` is executed before `sed` is even run and its result is substituted by your shell. I could do it with `perl` instead: `perl -pe 's|0|`uuidgen`/g` replaces each 0 by a different invocation of uuid. – Jean-Michaël Celerier Sep 04 '17 at 07:20
  • @Jean-MichaëlCelerier oh, I see. You are right. Then you can probably use `/e` as seen in posts like [How to change date format in sed?](https://stackoverflow.com/q/34071098/1983854). This will for sure run the command on every line. However, I doubt is going to be nicer than in Perl :) – fedorqui Sep 04 '17 at 07:26
  • 1
    Sorry, formatting was bad: `perl -pe 's|0|\`uuidgen\`|g'` – Jean-Michaël Celerier Sep 04 '17 at 08:50
  • @Jean-Michaël Celerier this doesn't run uuidgen mutiple times: ```~ echo '00' | perl -pe "s|0|`uuidgen` |g"``` ```6b748ce4-5e14-4939-9367-ede54b112e30 6b748ce4-5e14-4939-9367-ede54b112e30``` – peetasan Mar 10 '21 at 14:04
  • sorry, command is missing a "e". Also it must be single quotes, not double quotes. `echo 000 | perl -pe 's/0/\`uuidgen\`/ge'` – Jean-Michaël Celerier Mar 21 '21 at 17:25
  • @Jean-MichaëlCelerier are you replying to peetasan's comment? Better `@ping` them so they see your reply (quite a time-elapsed conversation you are having ;-D) – fedorqui Mar 21 '21 at 19:54
2

When the replacement string has newlines and spaces, you can use something else. We will try to insert the output of ls -l in the middle of some template file.

awk 'NR==FNR {a[NR]=$0;next}
    {print}
    /Insert index here/ {for (i=1; i <= length(a); i++) { print a[i] }}'
    <(ls -l) template.file

or

sed '/^Insert after this$/r'<(ls -l) template.file
Walter A
  • 19,067
  • 2
  • 23
  • 43
  • Thanks, but the awk example won't work for me, it waits forever. If I remove the line breaks, it runs, but doesn't do anything with the file. Also, what is 'index'? – bviktor Jan 15 '19 at 14:58
  • The awk searches for some string. In this exampl the string is `Insert index here`. When this line is found in `template.file` it will try to insert tje listing. Perhaps i should have said `/Insert here/`. – Walter A Jan 15 '19 at 17:21