作業ディレクトリのディレクトリ数を印刷しようとしています。何らかの理由で私のカウンターは増加しません。なんだか教えてください?
#!/bin/bash
n=0
for afile in $(ls)
do
if [ -d $afile ]
then
(( n ++ ))
fi
done
echo There are $n directories under the current directory $(pwd).
exit 0
奇妙なことに、このプログラムはls..(upディレクトリ)を通して繰り返されるようです。
for myfile in $(ls ..)
do
if [ -d "../$myfile" ]
then
echo "../$myfile (dir)"
else
echo ../$myfile
fi
done
exit 0
答え1
(現在のディレクトリから)非表示のディレクトリの数を数えるには、次のようにしますbash
。
shopt -s nullglob
set -- */
printf 'There are %d non-hidden subdirectories in %s\n' "$#" "$PWD"
隠しディレクトリの数を含めるには:
shopt -s dotglob nullglob
set -- */
printf 'There are %d subdirectories in %s\n' "$#" "$PWD"
このコードの目的は、スキーマを拡張し、*/
スキーマが拡張された後に名前の数を数えることです。このパターンはスラッシュで終わるのでただディレクトリ名(またはディレクトリへのシンボリックリンク名)に展開されます。
ディレクトリ名は位置引数などに割り当てられ、$1
これらの引数の数はシェルによって保持されます(したがって、計算するために実際にループを回す必要はありません)。$2
set
$#
bash
配列がより快適であると思われる場合は、次のようにします。
shopt -s dotglob nullglob
dirs=( */ )
printf 'There are %d subdirectories in %s\n' "${#dirs[@]}" "$PWD"
これは、位置パラメータの代わりに名前付き配列を使用することを除いて、本質的に同じです。
dotglob
のシェルオプションは、隠された名前と隠されていない名前のbash
両方と一致します。*
シェルnullglob
オプションを使用すると、一致しないパターンは何も拡張されません。
関連:
答え2
あなたのコードは私にはうまくいきますが、いくつかのバグがあり、場合によっては失敗します(たとえば、ファイル名にスペースが含まれている場合など)。
- まずはしないでください。lsを解析する。代わりに繰り返しのためにglobを使用してください。つまり、
$(ls)
。*
- 変数を読み取るときは、引用符で囲む必要があります。つまり、
"$foo"
代わりにを使用してください$foo
。引用しないと、シェルは出力を空白などのIFSに分割します。スクリプトを使用してこれをテストできます。スペースなしでいくつかのディレクトリを含め、スペースでテストします。電子のみが計算されます。
固定コードは次のとおりです。
#!/bin/bash
n=0
for afile in *
do
if [ -d "$afile" ]
then
(( n ++ ))
fi
done
echo There are $n directories under the current directory $(pwd).
exit 0
これが明らかであるかどうかはわかりませんが、スクリプトは現在のディレクトリで実行されます。