1

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
SamTzu
  • 71

1 Answers1

6

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.