如何不使用wc命令完成统计/usr/bin下首字母命令数的Bash脚本作业
问题:无需wc命令实现/usr/bin目录下字母开头命令统计
作业要求:编写名为counter.sh的Bash脚本,统计/usr/bin目录下以每个英文字母开头的命令数量,输出字母与对应数量的列表,排除非字母开头的命令,需使用循环和数组实现。原本用wc -l能完成,脚本如下:
for letter in {a..z} do echo "$letter $(ls /bin | grep "^$letter" | wc -l)" done
但作业禁止使用wc命令,求替代实现方法。
解决方案
直接用数组结合循环计数,完全不需要wc命令,脚本代码如下:
#!/bin/bash # 初始化26个元素的数组,对应a-z的计数,初始值都是0 declare -a counts=() for i in {0..25}; do counts[$i]=0 done # 遍历/usr/bin下的所有文件 for cmd in /usr/bin/*; do # 只取文件名,去掉前面的路径 cmd_name=$(basename "$cmd") # 提取首字符并转成小写,统一统计大小写开头的命令 first_char=${cmd_name:0:1} first_char_lower=$(echo "$first_char" | tr 'A-Z' 'a-z') # 判断首字符是不是小写字母 if [[ "$first_char_lower" =~ ^[a-z]$ ]]; then # 把字母转成数组索引:a对应0,b对应1...z对应25 index=$(( $(printf "%d" "'$first_char_lower") - $(printf "%d" "'a") )) # 对应计数加1 counts[$index]=$(( counts[$index] + 1 )) fi done # 遍历数组,输出每个字母和对应的数量 for i in {0..25}; do # 把索引转成对应的字母 letter=$(printf "\\$(printf "%o" $(( $(printf "%d" "'a") + i )) )") echo "$letter ${counts[$i]}" done
代码说明
- 数组初始化:先建一个26位的数组,每个位置对应a-z的初始计数0,避免后续计数出错。
- 文件遍历:直接遍历
/usr/bin/*,比用ls更安全,能避免文件名带空格的问题。 - 首字符处理:转小写是为了把
Cat和cat都算到c开头的统计里,符合常规需求;正则判断确保只处理字母开头的命令。 - 计数逻辑:利用ASCII码计算索引,a的ASCII码是97,所以用当前字母的ASCII码减97就能得到对应的数组位置,然后计数自增。
- 结果输出:把数组索引再转回字母,逐个输出字母和对应计数。
内容的提问来源于stack exchange,提问作者Mustafa Yilmaz
相关产品推荐
相关产品推荐

