I'm trying to remove all tech\
strings in a file.php that has meny lines like this "tech\/what-is-vnet"
.
Why does this command do nothing?
sed -i "s~tech\~~g" file.php
sed
treats backslash as an escape character, so when it sees \~
in the command string, it interprets it as meaning that the ~
has been escaped, and should be treated as part of the match string rather than a delimiter. To prevent this, you need to escape the backslash itself, with another backslash:
sed -i 's~tech\\~~g' file.php
Also, note that I switched from using double-quotes to single-quotes. That's because the shell (assuming Bourne-like shells here) also treats backslashes as escapes (except when they're in single-quotes), so if it saw \\
in a double-quoted string it'd parse that as an escaped backslash, and only pass the second backslash to sed
. If you wanted to use double-quotes, you'd need to add another backslash before each of the backslashes you wanted to pass to sed
, giving 4 backslashes total:
sed -i "s~tech\\\\~~g" file.php
...which is one of the reasons single-quotes are recommended for things like sed
and grep
patterns that might contain shell metacharacters.
p.s. obligatory relevant xkcd: https://xkcd.com/1638/.
p.p.s. Actually, three backslashes would work in double-quotes, because of a quirk of how the shell handles escaping characters like ~
that the shell doesn't consider escape-worthy. But taking that into account just makes this mess even more confusing than it already is.