我想知道是否有一种方法可以使用循环来检查当前目录中的文件数量,而无需使用管道。
如果我有 3 个文件,则输出应该是 3。
我知道你可以轻松做到
ls | wc -l
但我想知道是否有办法将其放入循环而不使用管道。
谢谢
答案1
在 bash 中,您可以将所有文件添加到一个数组以及echo
数组中的元素数量:
arr=(*)
echo "${#arr[@]}"
答案2
干得好 :
files_num=0
for i in *; do
(( files_num++ ))
done
echo $files_num
答案3
当然,您可以使用循环,但是当您不需要循环时为什么要使用循环呢?
shell 具有枚举目录中的文件并对它们进行计数的所有工具。基本思想(封装在函数中)是
count_files () {
set *
echo $#
}
即,将位置参数设置为当前目录中的文件名列表并打印位置参数的数量。这在几种边缘情况下会崩溃:
- 如果第一个文件名以 开头
-
,则它被解释为 的选项set
。用 轻松解决set -- *
。 - 如果没有匹配的文件,则
*
保持不变。如果您想移植到 POSIX shell,则需要处理这种特殊情况。如果您有能力要求 ksh、bash 或 zsh,他们有更好的方法。 - 这不包括点文件(以 开头的文件
.
)。它们需要单独包含在内。 glob.*
列出了点文件,包括.
和..
除了 pdksh 以及 Forsyth shell 和 zsh 的所有其他后代(并且bash
ifGLOBIGNORE
不为空)。假设这些不应该被计算在内,只需减去2即可。
POSIX 解决方案:
count_files () {
set -- * .*
if [ "$1" = "*" ] && ! [ -e "$1" ] && ! [ -L "$1" ]; then
shift # Remove the * which didn't match any file
fi
echo $#
}
Ksh93解决方案:
function count_files {
typeset FIGNORE='@(.|..)'
set -- ~(N)
echo $#
}
重击解决方案:
count_files () (
shopt -s dotglob nullglob
set -- *
echo $#
)
zsh解决方案:
count_files () {
emulate -LR zsh
set -- *(DN)
echo $#
}