我正在尝试打印工作目录中的目录数。由于某种原因,我的计数器没有增加。你能告诉我为什么吗?
#!/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 ..(上目录)进行迭代
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
,并且这些参数的数量由 shell 保留(因此不需要实际循环它们来计数)。$2
set
$#
如果您对bash
数组感觉更舒服:
shopt -s dotglob nullglob
dirs=( */ )
printf 'There are %d subdirectories in %s\n' "${#dirs[@]}" "$PWD"
这本质上是同一件事,只不过它使用命名数组而不是位置参数。
dotglob
中的 shell 选项将bash
匹配*
隐藏名称和非隐藏名称。 shellnullglob
选项将使不匹配的模式扩展为空。
有关的:
答案2
您的代码对我来说工作正常,但其中存在一些错误,在某些情况下会失败(例如,如果文件名中包含空格)。
- 首先,不要解析ls. 而是使用 glob 进行迭代。即,而不是
$(ls)
,使用*
。 - 读取变量时,应该引用它们,即使用
"$foo"
而不是$foo
。如果不引用它们,shell 将在 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
我不确定这是否显而易见,但脚本将在当前目录中运行。