背景介绍
我需要统计某个文件夹下的文件个数,网上给出的解决方案是:
1、 统计当前文件夹下文件的个数
ls -l |grep "^-"|wc -l
2、 统计当前文件夹下目录的个数
ls -l |grep "^d"|wc -l
3、统计当前文件夹下文件的个数,包括子文件夹里的
ls -lR|grep "^-"|wc -l
4、统计文件夹下目录的个数,包括子文件夹里的
ls -lR|grep "^d"|wc -l
grep "^-"
这里将长列表输出信息过滤一部分,只保留一般文件,如果只保留目录就是 ^d
wc -l
统计输出信息的行数,因为已经过滤得只剩一般文件了,所以统计结果就是一般文件信息的行数,又由于一行信息对应一个文件,所以也就是文件的个数。
第一版代码
所以,一开始我的代码是
#!/bin/bash
countFiles() {
local dir=$1
local files
files=$(ls -lR "$dir" | grep "^-" | wc -l)
echo "${dir}共计包含${files}个文件"
}
遇到 ShellCheck: Consider using grep -c instead of grep|wc -l. 问题
详见 Wiki SC2126
This is purely a stylistic issue. grep can count lines without piping to wc.
修改ls -lR "$dir" | grep "^-" | wc -l
为ls -lR "$dir" | grep -c "^-"
可以去掉一个连接到wc
的管道。
SC2010 和 SC2012
但是,更加麻烦的是另一个 ShellCheck:
Don't use ls | grep. Use a glob or a for loop with a condition to allow non-alphanumeric filenames.
详见 Wiki SC2010
针对这个问题,我本想尝试用 来解决,但是 files=$(ls -l "$dir/"* | wc -l)
ls -l /direcotry/*
打印出来的结果不尽如人意:
[root@mongodb10 shell]# ls -l /opt/mongo/*
/opt/mongo/config:
总用量 4
drwxr-xr-x 4 root root 4096 6月 13 16:30 data
drwxr-xr-x 2 root root 45 6月 9 15:20 log
/opt/mongo/mongos:
总用量 0
drwxr-xr-x 2 root root 42 6月 9 15:29 log
/opt/mongo/shard1:
总用量 4
drwxr-xr-x 4 root root 4096 6月 13 16:29 data
drwxr-xr-x 2 root root 42 6月 9 15:23 log
/opt/mongo/shard2:
总用量 8
drwxr-xr-x 4 root root 4096 6月 13 16:30 data
drwxr-xr-x 2 root root 42 6月 9 15:23 log
[root@mongodb10 shell]#
此时,又出现了一个新的 ShellCheck 提示:
Use find instead of ls to better handle non-alphanumeric filenames.
详见 Wiki SC2012
建议我们使用find
命令来代替ls
用 find 代替 ls
统计当前文件夹下文件的个数,包括子文件夹里的
find -type f|wc -l
统计文件夹下目录的个数,包括子文件夹里的
find -type d|wc -l
所以,我的脚本也随之修改:
#!/bin/bash
countFiles() {
local dir=$1
local files
files=$(find "$dir/"* | wc -l)
echo "${dir}共计包含${files}个文件"
}
countFiles "$1"