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.
cat file.txt | sed -r 's/([0-9]+)/\1,/g'
{02, 12, 04, 01, 07, 10, 11, 06, 08, 05, 03, 15, 13, 00, 14, 09,},
{14, 11, 02, 12, 04, 07, 13, 01, 05, 00, 15, 10, 03, 09, 08, 06,},
{04, 02, 01, 11, 10, 13, 07, 08, 15, 09, 12, 05, 06, 03, 00, 14,},
{11, 08, 12, 07, 01, 14, 02, 13, 06, 15, 00, 09, 10, 04, 05, 03,}
Explanation:
First capturing group ([0-9]+)
Match a single character (i.e. number) present in the table [0-9]+
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
0-9 a single character in the range between 0 (index 48) and 9 (index 57) (case sensitive)
In other words, the [0-9]+ pattern matches an integer number (without decimals) even Inside longer strings, even words.
\1 is called a "back reference" or "special escapes" in the sed documentation. It refers to the corresponding matching sub-expressions in the regexp. In other words, in this example, it inserts the contents of each captured number in the table followed by comma.
Best Answer
basename
from the GNU coreutils can help you doing this job:If you already know the extension of the file, you can invoke
basename
using the syntaxbasename NAME [SUFFIX]
in order to remove it:Or another option would be cutting everything after the last dot using
sed
: