Why doesn't ${PATH//:/\n} output each path on a new line?

Viewed 61

Suppose

PATH=/this/is/path1:/this/is/path2:/this/is/path3

Why does

echo "${PATH//:/\n}" or echo -e "${PATH//:/\n}"

not output

this/is/path1
this/is/path2
this/is/path3

This is bash 4.4.20.

2 Answers

Stuff inside ${var//<here>/<and here>} is escaped with \, so that you could write \} or \/. Like:

$ var=abc; echo "${var//b/\}}"
a}c

The \n is not special sequence, so it's just n:

$ var=abc; echo "${var//b/\n}"
anc

So with "${PATH//:/\n}" you are just only replacing : with n. Either replace : with an actual newline:

echo "${PATH//:/$'\n'}"
# or an actual actual newline
echo "${PATH//:/
}"

or you seem to want to replace it by a sequence of two characters \n and then use echo -e to tranform \n into newlines:

echo -e "${PATH//:/\\n}"

The bash operator ${var//pattern/string/ } is a variable expansion, which takes as input the value of the variable var, then replaces all matches of pattern by string.

In your example, to goal is to replace each separator : by \n, and print them with echo -e as a newline.

But to make it work, it is necessary to double the \ to protect it, so the correct command is

echo -e "${PATH//:/\\n}"

For further informations, see in the reference manual the paragraph ${parameter/pattern/string}.

Related