web-dev-qa-db-ja.com

$ {#array} vs $ {#array [@]}

私が知る限り、${#array[@]}${#array}の両方が$arrayの要素の数に評価されます。長い形式(${#array[@]})を好む理由はありますか?

6
kjo

Zshでは、個人的な好み。他のシェルでは、$arrayは最初の要素にのみ展開できるため、${#array}は最初の要素の長さを出力します。

したがって、シェル間でもう少し移植性を高めたい場合は、[@]を指定すると機能します。

Zshでは、$array$array[*]と同じように展開されますが、引用符で囲まれているかどうかによって異なります。それらが二重引用符で囲まれている場合、"$array"は展開され、デフォルトではスペースであるIFSの最初の文字で区切られます。

zsh% touch {1..10}; a=(*)
zsh% printf '<%s> ' $a
<1> <10> <2> <3> <4> <5> <6> <7> <8> <9>     
zsh% printf '<%s> ' "$a"
<1 10 2 3 4 5 6 7 8 9> 
zsh% IFS=:
zsh% print "$a"
1:10:2:3:4:5:6:7:8:9
zsh% print "$a[@]"
1 10 2 3 4 5 6 7 8 9
zsh% IFS=$' \t\n'
zsh% rm "$a"
rm: cannot remove ‘1 10 2 3 4 5 6 7 8 9’: No such file or directory

IFSを変更する必要がほとんどないため、元の「個人設定」の応答が促されました。ただし、#フラグなしで使用した場合、2つの間にいくつかの違いがあることを明確にするために、それらは非常に微妙です。

$array[@]も、引用符で囲まれているかどうかによって動作が変わらないので、私は好きです。それと要素が持つ可能性のある内部空白は保持されます。

10
llua

他のコードと同様に、コードが読みやすく理解しやすいほど、他の人(または将来のあなた)が保守しやすくなります。選択肢があり、そのうちの1つがあいまいな場合は、もう1つを選択します。

さらに、シェルスクリプトに移植性が必要な場合は、bashで正しく機能するのはシェルスクリプトだけです。

4
bahamat

配列をサポートするほとんどのシェル(bashksh93、およびpdkshでテストしました)では、${#array}${array[0]}の長さを示します。 ${#array[@]}は、配列内の要素の数を示します。これは論理的です。"${array}"は配列の要素0を返し、"${#array}"はその長さを返します。

4