13

I'd like to replace a string within a variable, e.g.:

Test=Today, 12:34

I'd like to replace the "Today" within the variable Test with a Date variable I declared before.

I tried using the sed command:

sed -i -e "s/Today/$Date" '$Test'

But it would just print out an error and the file '$Test' is not known. Is using sed only possible with text files?

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
X3nion
  • 181
  • 1
  • 1
  • 9
  • 2
    `$Test` is not a file. You can use: `sed '....' <<< "$Test"` or better do it in bash itself using `"${Test/Today/$Date}"` – anubhava Sep 02 '20 at 14:26
  • 1
    In addition to what @anubhava said, note that in bash, variable expansion will not work in single quotes. If you want to expand the Test variable, you can either leave it unquoted `$Test` or put it in double-quotes `"$Test"`. If you use single quotes it will be treated as a string literal. – antun Sep 02 '20 at 14:33
  • When I write only the command "${Test/Today/$Date}", this doesn't work. What am I missing? – X3nion Sep 02 '20 at 14:44
  • 1
    Does this answer your question? [Replace one substring for another string in shell script](https://stackoverflow.com/questions/13210880/replace-one-substring-for-another-string-in-shell-script) – Let's try Sep 02 '20 at 14:58
  • 3
    `"${Test/Today/$Date}"` isn't a command, it's an expression that produces a string. You need to do something with that string, like set a variable to it (`Test="${Test/Today/$Date}"` would replace the current value of `Test` with the modified version), print it (`echo "${Test/Today/$Date}"`), or something like that. – Gordon Davisson Sep 02 '20 at 15:01

3 Answers3

11

First, that's a syntax error.

$: Test=Today, 12:34
bash: 12:34: command not found

Put some quoting on it.

$: Test="Today, 12:34"
$: Test='Today, 12:34'
$: Test=Today,\ 12:34

Then you can just use bash's built-in parameter expansion:

$: Test='Today, 12:34'
$: Date=12.12.2000
$: Test="${Test/Today/$Date}"
$: echo "$Test"
12.12.2000, 12:34
Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
8

This works for me:

Test="Today, 12:34"
Date=12.12.2000
sed 's/Today/'"$Date"'/g' <<<"$Test"

Edit: If you would like to change the variable Test, like mentioned in the comment, you need the assignment:

Test="Today, 12:34"
Date=12.12.2000
Test=$(sed 's/Today/'"$Date"'/g' <<<"$Test")
TheSlater
  • 642
  • 1
  • 4
  • 11
3

To do this you don't need to make any use of sed and can, instead, make use of the little-known, but extremely handy feature of Bash called parameter expansion described here. I only know about this because it came up in a job interview once and the interviewer shared it with me then left me to clean my brains up off the floor...

Test='Today, 12:34'
Date='12.12.2000'
echo "${Test/Today/$Date}"
---
12.12.2000, 12:34

As I said, this blew my mind in that job interview. I didn't get the job, but I've used this feature just about every day since.

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
  • 1
    Parameter expansion is quite useful for changing file endings: `for f in *.pdf; do echo "${f/%.pdf/.test}"; done`. This will print each file name with the last occurrence of ".pdf" changed to ".test". – Matthias Braun Jul 25 '23 at 21:26