8
votes

In bash, newline characters are preserved through command substitution:

$ TEST="$(echo 'a
  b
  c
  ')" && echo "$TEST"
# →
a
b
c

However, when I try to do the same in fish shell, the newline characters get converted into spaces:

$ set TEST (echo "a
  b
  c
  "); and echo "$TEST"
# →
a b c

How to make fish save the newline characters as newlines?

2
Fish shell tries way too hard to be different. I'd give anything for a shell with bash as the scripting language and fish's interactive features like syntax highlighting and history.BallpointBen

2 Answers

5
votes

Conceptually, they are not converted into spaces: you are getting a list!

> echo -e "1\n2\n3" > foo
> cat foo
1
2
3
> set myFoo (cat foo)
> echo $myFoo
1 2 3
> echo $myFoo[0..2]
1 2

Therefore we apply the machinery available for lists; for instance, joining with a separator (note the extra backspace to get rid of undesirable spaces):

> echo {\b$myFoo}\n
1
2
3
 # extra newline here

This is not ideal; string does it better:

> string join \n $myFoo
1
2
3
2
votes

Exact issue discussed on fish users mailing list: Discussed on fish users mailing list: http://sourceforge.net/p/fish/mailman/message/33644843/

You have to modify the IFS variable to do this:

$ set out (seq 5)
$ echo "$out"
1 2 3 4 5

$ set oldIFS "$IFS"
$ set IFS ""
$ set out (seq 5)
$ echo "$out"
1
2
3
4
5
$ set IFS "$oldIFS"