按文件扩展名统计用户组文件数:Bash脚本异常求解决
问题排查:按文件扩展名统计用户组文件数量的Bash脚本修正
我需要完成一个练习:写一个脚本,对目录里的普通文件按扩展名分类,列出每个扩展名对应的、拥有至少一个该扩展名文件的用户组,以及各组的文件数量。
示例输入
-rw------- 2 utente1 staff 4096 2007-02-10 14:28 doc1.pdf -rw-r--r-- 1 utente1 staff 102 2007-02-11 02:05 doc2.pdf -rw-r--r-- 1 utente2 users 3145 2007-01-16 01:48 rel.tex -rw------- 1 utente2 users 268 2007-01-16 10:37 song1.mp3 -rw-r--r-- 4 utente3 staff 4096 2006-04-28 19:29 text1.tex -rw-r--r-- 1 utente3 staff 11 2007-05-02 12:10 text2.tex
预期输出
.tex: users 1 staff 2 .pdf: staff 2 .mp3: users 1
我的错误脚本
我写的Bash脚本运行异常,会输出不存在的数值,求修正:
#!/bin/bash groups=$(awk ' {print $4}' group.txt | sort | uniq) echo .tex: for group in $groups do awk -v gr=$group ' ($4==gr && $1~"^-") {somma=somma+$5; num=num+1}; END {if(somma!=0) {print gr,num,"("somma")"}}' group.txt done echo .pdf: for group in $groups do awk -v gr=$group ' ($4==gr && $1~"^-") {somma=somma+$5; num=num+1}; END {if(somma!=0) {print gr,num,"("somma")"}}' group.txt done echo .mp3: for group in $groups do awk -v gr=$group ' ($4==gr && $1~"^-") {somma=somma+$5; num=num+1}; END {if(somma!=0) {print gr,num,"("somma")"}}' group.txt done
问题分析
你的脚本存在几个核心问题:
- 未过滤对应扩展名文件:只判断了普通文件和用户组匹配,但完全没筛选对应扩展名,导致统计的是该组所有普通文件的数量,不是目标扩展名的。
- 逻辑冗余重复:每个扩展名单独写循环,重复执行相同逻辑,效率低且易出错。
- 多余统计文件大小:需求只需要文件数量,脚本里统计的
$5(文件大小)属于额外计算,还干扰输出格式。 - 输出格式不符预期:预期是每个扩展名一行,后面跟所有符合条件的组和数量,你的脚本会每个组单独输出一行。
修正后的脚本
直接用awk一次性处理所有逻辑,高效又简洁:
#!/bin/bash # 若要处理当前目录真实文件,可将group.txt替换为find . -maxdepth 1 -type f -ls awk ' # 仅处理普通文件 $1 ~ /^-/ { # 提取扩展名:拆分文件名,取最后一个.后的部分,无扩展名则跳过 split($NF, name, /\./) if (length(name) > 1) { ext = "." name[length(name)] # 统计每个扩展名+用户组的文件数量 count[ext, $4]++ } } END { # 收集所有唯一扩展名 for (key in count) { split(key, arr, SUBSEP) exts[arr[1]] = 1 } # 按扩展名输出对应组和数量 for (ext in exts) { printf "%s:", ext for (group in count) { split(group, arr, SUBSEP) if (arr[1] == ext) { printf " %s %d", arr[2], count[group] } } printf "\n" } } ' group.txt
修正说明
- 扩展名提取:用
split拆分文件名,取最后一个.后的字段,能正确处理带多个.的文件名(比如a.b.txt会提取.txt)。 - 统计逻辑:用二维关联数组
count[ext, $4]++直接统计,避免重复遍历文件。 - 输出格式:先收集所有扩展名,再逐个输出对应的组和数量,完全匹配预期格式。
- 灵活性:如果要处理当前目录的真实文件,把
group.txt替换为find . -maxdepth 1 -type f -ls(比ls -l更可靠,避免文件名含空格的问题)。
内容的提问来源于stack exchange,提问作者saretta2
相关产品推荐
相关产品推荐

