Bashの配列の長さはどのくらいで、「*」と「@」を区別するには?

Bashの配列の長さはどのくらいで、「*」と「@」を区別するには?

次のサンプルスクリプトがありますが、配列の長さが正確に何であるかを知りたいです。バイト、文字、または他のものですか?

#!/bin/bash

# Arrays
# @ vs. *

ape=( "Apple Banana" "Emacs Window" "Panda Bamboo Nature" )
cape=( 'Ping Pong' 'King Kong' 'King Fisher Club' 'Blurb' )
jade=( ally belly cally delly )

echo Expansion with \*
echo ${ape[*]}
echo ${cape[*]}
echo -e "${jade[*]}\n"

echo Expansion with \@
echo ${ape[@]}
echo ${cape[*]}
echo -e "${jade[@]}\n"

echo Elements with \*
echo ${#ape[*]}
echo ${#cape[*]}
echo ${#jade[*]}

echo Elements with \@
echo ${#ape[@]}
echo ${#cape[@]}
echo ${#jade[*]}

echo -e "\nLength"
echo ${#ape}
echo ${#cape}
echo ${#jade}

私が知っているマニュアルページでは、配列拡張は単語が二重引用符で囲まれている場合とは異なりますが、*違いはありません。@どちらの場合も、同じ結果が得られるのはなぜですか?

出力は次のとおりです。

Expansion with *
Apple Banana Emacs Window Panda Bamboo Nature
Ping Pong King Kong King Fisher Club Blurb
ally belly cally delly

Expansion with @
Apple Banana Emacs Window Panda Bamboo Nature
Ping Pong King Kong King Fisher Club Blurb
ally belly cally delly

Elements with *
3
4
4
Elements with @
3
4
4

Length
12
9
4

ベストアンサー1

*配列を単一の文字列に拡張し、@個別に引用した文字列に拡張する様子を見逃しました。

printf 'string "%s"\n' "${cape[*]}"

これは生産します

string "Ping Pong King Kong King Fisher Club Blurb"

そして

printf 'string "%s"\n' "${cape[@]}"

これは生産します

string "Ping Pong"
string "King Kong"
string "King Fisher Club"
string "Blurb"

echo単に引数を連結して印刷するのではなく、書式printf文字列を引数で埋め、より多くの引数が指定された場合は同じ書式を繰り返すことに注意してください。

返品、

for s in "${cape[*]}"; do
    echo "$s"
done

単一の出力ラインを生成します(単一の文字列のみを繰り返します)。

for s in "${cape[@]}"; do
    echo "$s"
done

各配列要素に対して1つずつ生成します。


${array[*]}${array[@]}何らかの理由で単語の区切りとファイル名のグロービングを明示的に呼び出す場合を除き、常におよび拡張の周りに二重引用符を使用することをお勧めします。*or の使用は、@配列要素がすべて 1 つの文字列で必要かどうか個別に引用されるかによって異なります。

私の経験ではほとんど使用されていません[*]


配列の長さを取得するときに*どれを使用するかは問題ではありません。@ただし、両方を使用しないと、配列の最初の要素の文字長が得られます。

おすすめ記事