如果这样做ls -1 target_dir | wc -l
,我会得到目录中文件的计数。我觉得这有点麻烦。有没有更优雅或更简洁的方式?
答案1
假设 bash 4+(任何受支持的 Ubuntu 版本都有):
num_files() (
shopt -s nullglob
cd -P -- "${1-.}" || return
set -- *
echo "$#"
)
称其为num_files [dir]
.dir
是可选的,否则使用当前目录。您的原始版本不计算隐藏文件,因此也不计算隐藏文件。如果你想要的话,shopt -s dotglob
之前set -- *
。
您最初的示例不仅计算常规文件,还计算目录和其他设备 - 如果您确实只需要常规文件(包括常规文件的符号链接),则需要检查它们:
num_files() (
local count=0
shopt -s nullglob
cd -P -- "${1-.}" || return
for file in *; do
[[ -f $file ]] && let count++
done
echo "$count"
)
如果你有 GNU find,类似这样的东西也是一个选项(请注意,这包括隐藏文件,而你的原始命令没有这样做):
num_files() {
find "${1-.}" -maxdepth 1 -type f -printf x | wc -c
}
(如果您还想计算常规文件的符号链接,请更改-type
为)。-xtype
答案2
f=(target_dir/*);echo ${#f[*]}
对于名称中包含空格、换行符等的文件可以正常工作。
答案3
ls
仅当直接输出到终端时才是多列,可以删除“-1”选项,可以删除wc
“-l”选项,只读取第一个值(懒惰的解决方案,不用于法律证据,刑事调查、关键任务、战术行动..)。
ls target | wc
答案4
到目前为止,亚伦的方法是唯一比您自己的方法更简洁的方法。您的方法的更正确版本可能如下所示:
ls -aR1q | grep -Ecv '^\./|/$|^$'
这会递归地列出所有文件(而不是目录),每行一个,包括当前目录下的 .dotfiles,根据需要使用 shell glob 来替换不可打印的字符。 grep 过滤掉任何父目录列表或 .. 或 */ 或空行 - 因此每个文件应该只有一行 - grep 返回给您的总计数。如果您还希望包含子目录,请执行以下操作:
ls -aR1q | grep -Ecv '^\.{1,2}/|^$'
-R
如果您不想要递归结果,请删除任一情况。