2

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.

ragnacode
  • 332
  • 3
  • 13
  • Try: `echo "${PATH//:/$'\n'}"` – anubhava Apr 20 '21 at 13:46
  • 2
    `echo "${PATH//:/\n}"` works for me in `zsh`, and `echo "${PATH//:/$'\n'}"` works for me in `bash`. – 0x5453 Apr 20 '21 at 13:55
  • 1
    Both of your bash suggestions work for me. What is the role of the second $? – ragnacode Apr 20 '21 at 13:59
  • In bash, "\n" is simply a backslash followed by the letter _n_, as you can see by doing a `printf %s "\n"`. You would need this to translate to a newline when printing. From the man-page for `echo` : _-e : enable interpretation of backslash escapes_ – user1934428 Apr 20 '21 at 14:12
  • 1
    Please add your bash version. Also, take a look at [Echo newline in Bash prints literal \n](https://stackoverflow.com/questions/8467424/echo-newline-in-bash-prints-literal-n) – 0stone0 Apr 20 '21 at 14:16

2 Answers2

3

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}"
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Or a POSIX shell alternative: `(IFS=:;printf %s\\n $PATH)` parenthesis sub-shell is to preserve IFS. or `OIFS=$IFS;IFS=:;printf %s\\n $PATH;IFS=$OIFS` without a sub-shell. – Léa Gris Apr 20 '21 at 15:47
1

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}.

Edouard Thiel
  • 5,878
  • 25
  • 33