Linux Madness: Bash Substring Replacement

Wed 2014-02-05

So I was investigating some strange bug in nanoblogger where it would sometimes garble relative links, when I found the following gem in a shell script:


where for example:


So what does this fence of / and \\ do except of being visually interesting?

We can test it interactively in a shell:

$ BASE_URL="../../../"
$ echo "${BASE_URL//\//\\/}"

So it seems to escape all our / as \/ -- but how?

To see this, one has to know how to do substring replacement in bash. In greater detail this is explained here: tldp.

To replace all matches of substring in string with replacement one has to run

        AA         B

Here the // above AA means »replace all matches«, the / over B is used as a separator.

In our case we want to replace all occurrences of / in $string with an escaped \/.

But as / is used as a separator between substring and string we have to escape it as \/ (11).

To further complicate things, we want a literal backslash in our replacement, so we have to escape that one too as \\/ (222).

When we put everything together, we get our nice expression form the beginning:


TL;DR: Not only in perl is it possible to produce code in »write-only« style!


This text by Ludger Sandig is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.