First thing: don't write to a file you're reading from, you're likely to end up erasing it. Use the inplace-edit feature (-i
) instead.
Next, inside hard quotes ('
), variable substitution doesn't operate, so you'll need to do something else to get the expanded $PATH
substituted in there.
Lastly, $PATH
is very likely to contain /
characters, which would break the substitution syntax for sed
, so you'll need to use another separator.
Assuming your paths never contain ;
s, try (after having backed-up your current file of course):
sed -i 's;^PATH=.*;PATH='"$PATH"';' .bashrc
The match part of the substitution means: match a string that starts with (^
) the string PATH=
and followed by any character (.
) any number of times (*
). I.e. it will match lines that start with PATH=
completely, but not lines that have PATH=
somewhere in the middle. The .*
is important because you want to replace the whole line (try without it to see what happens).
The quoting to get $PATH
substituted inside the replacement is necessary to account for cases where $PATH
would contain whitespace characters.
Demo:
$ foo=bar
$ echo hello | sed -e 's/hello/$foo/'
$foo
Env. vars are not substituted inside hard quotes. So you get a literal $foo
there. Now let the shell expand it by bringing it out of the hard quotes:
$ foo=bar
$ echo hello | sed -e 's/hello/'$foo'/'
bar
Ok! But this isn't safe:
$ foo="bar baz"
$ echo hello | sed -e 's/hello/'$foo'/'
sed: -e expression #1, char 11: unterminated `s' command
sed
received two arguments after -e
above: s/hello/bar
and baz/
, separately. Not good. To fix that, you need a bit more quotes:
$ foo="bar baz"
$ echo hello | sed -e 's/hello/'"$foo"'/'
bar baz
Putting an environment variable inside "
quotes is something you should pretty much always do when you're passing it as an argument to something else, otherwise (assuming $IFS
hasn't been changed) it will get split on whitespace.