IFS のセパレーターが配列拡張に機能しないのはなぜですか?

IFS のセパレーターが配列拡張に機能しないのはなぜですか?

セパレータの変更をシェルではなく次の echo コマンドのみに制限したいと思います。

$ myarr=(1 2 3)

$ echo $( IFS="|"; echo "${myarr[@]}" )
1 2 3

セパレーターが配列拡張に機能しないのはなぜですか? ありがとうございます。

答え1

POSIXから、に関して$*:

フィールド分割が実行されないコンテキストで拡張が発生した場合、初期フィールドは結合されて単一のフィールドを形成し、各パラメータの値は、変数に少なくとも 1 文字が含まれているIFS場合は変数の最初の文字で区切られIFS、設定されていない<space>場合はで区切られ、ヌル文字列に設定されているIFS場合は区切られません。IFS

$*単語を区切り文字で結合するには、または を${array[*]}使用する必要がありますbash

$ set -- word1 word2 word3 "some other thing" word4
$ IFS='|'
$ echo "$*"
word1|word2|word3|some other thing|word4

または、配列を使用する場合bash:

$ arr=( word1 word2 word3 "some other thing" word4 )
$ IFS='|'
$ echo "${arr[*]}"
word1|word2|word3|some other thing|word4

コードを使用すると:

$ myarr=( 1 2 3 )
$ echo "$( IFS="|"; echo "${myarr[*]}" )"
1|2|3

答え2

比較する:

$ myarr=(1 2 3)
$ printf '%s\n' $( IFS="|"; echo "${myarr[@]}" )
1
2
3
$ printf '%s\n' $( IFS="|"; echo "${myarr[*]}" )
1|2|3

man bash より:

@
… 展開が二重引用符内で行われる場合、各パラメータは別々の単語に展開されます。つまり、「$@」は「$1」「$2」と同等です...

*
… 二重引用符内で展開が行われると、1つの単語に展開され、IFS特殊変数の最初の文字で区切られた各パラメータの値。 あれは、「$*」は「$1c$2c...」と同等です。ここで、c は IFS 変数の値の最初の文字です。

上記の説明は位置パラメータに関するものですが、配列の拡張にも適用されます。

関連情報