Why doesn't the separator from IFS work for array expansion?
From POSIX, regarding $*
:
When the expansion occurs in a context where field splitting will not be performed, the initial fields shall be joined to form a single field with the value of each parameter separated by the first character of the
IFS
variable ifIFS
contains at least one character, or separated by a<space>
ifIFS
is unset, or with no separation ifIFS
is set to a null string.
To join words with a separator, you will have to use $*
, or ${array[*]}
in bash
:
$ set -- word1 word2 word3 "some other thing" word4
$ IFS='|'
$ echo "$*"
word1|word2|word3|some other thing|word4
Or, with an array in bash
:
$ arr=( word1 word2 word3 "some other thing" word4 )
$ IFS='|'
$ echo "${arr[*]}"
word1|word2|word3|some other thing|word4
With your code:
$ myarr=( 1 2 3 )
$ echo "$( IFS="|"; echo "${myarr[*]}" )"
1|2|3
Compare:
$ myarr=(1 2 3)
$ printf '%s\n' $( IFS="|"; echo "${myarr[@]}" )
1
2
3
$ printf '%s\n' $( IFS="|"; echo "${myarr[*]}" )
1|2|3
From man bash:
@
… When the expansion occurs within double quotes, each parameter expands to a separate word. That is, "$@" is equivalent to "$1" "$2" ...*
… When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable. That is, "$*" is equivalent to "$1c$2c...", where c is the first character of the value of the IFS variable.
The description above is for positional parameters but it also apply to array expansions.