web-dev-qa-db-ja.com

zshスクリプトで配列の長さを見つける

配列の長さを見つける方法はありますか*(ファイル名)forループを使用せずにzshで変数をインクリメントしますか?

私は素朴にecho ${#*[@]}が機能しませんでした。 (bash構文も歓迎します)

2
Cristiano

${#*[@]}は、$*または$@とも呼ばれる$argv配列の長さになります。これは、位置パラメーターの配列です(スクリプトまたは関数の場合は、スクリプトまたは関数が受け取った引数です)。そのためには$#を使用したいのですが。

*だけが単なるグロブパターンです。リストのコンテキストでは、そのパターンに一致する現在のディレクトリ内のファイルのリストに展開されます。 *は任意の文字列に一致するパターンであるため、現在のディレクトリ内のすべてのファイル名に展開されます(hiddenのものを除く)。

次に、展開する*リストコンテキストを見つけて、結果の引数の数を数える必要があります。 1つの方法は、無名関数を使用することです。

() {echo There are $# non hidden files in the current directory} *(N)

*の代わりに、*である*(N)を使用しましたが、N(nullglobの場合)グロブ修飾子を使用して、*パターンがどのファイルとも一致しない場合にレポートする代わりにエラー、それはまったく何にも拡大しません。

次に、*(N)の展開がその無名関数に渡されます。その無名関数内では、そのファイルのリストは$@/$argv配列で使用でき、$#$#argv$#@$#*と同じ、または${#argv[@]}のような厄介なksh構文でも同じ)で配列の長さを取得します.

4
files=(*)
printf 'There are %d files\n' "${#files[@]}"

または

set -- *
printf 'There are %d files\n' "$#"

最初に配列に名前を付ける(上記でfilesを使用したように)か、2番目の例で行ったように、ワイルドカードを使用して組み込み配列$@を使用する必要があります。前者では、配列の「長さ」(ファイル数)は${#arrayname[@]}構文で行われます。組み込み配列の要素数は$#にあります。

2
Jeff Schaller