Bash脚本实现grep匹配行数与wc总行数的浮点除法计算
问题描述
我正在编写一个Bash脚本,需要完成两项操作:
- 用
grep -c "pattern" f*统计目录中各文件匹配指定模式的行数; - 用
wc -l f*统计目录中各文件的总行数。
我尝试将前者结果除以后者得到浮点结果,试过以下for循环:
for i in $a do printf "%f\n" $(($b/$a) echo i done
但返回错误:syntax error in expression (error token is "first file in directory");也尝试过bc "$b/$a",同样无法运行。现请求可行解决方案。
示例输入:grep -c *f输出:
myfile1 500 myfile2 0 myfile3 14 myfile4 18
wc -l *f输出:
myfile1 500 myfile2 500 myfile3 500 myfile4 238
期望输出:
myfile1 1 myfile2 0 myfile3 0.28 myfile4 0.07
解决方案
方案一:用join+awk快速合并计算(推荐)
利用进程替换和文本处理工具,直接合并两个命令的输出并计算比值,是最简洁的方式:
join <(grep -c "pattern" f* | sort) <(wc -l f* | grep -v total | sort) | awk '{ratio = $2 / $3; printf "%s %.2f\n", $1, ratio}'
说明:
<(command)是Bash进程替换,把命令输出当作临时文件供join使用;grep -v total用来过滤wc -l输出末尾的总行统计行;join默认按第一列(文件名)合并两个结果,得到每行格式为文件名 grep匹配行数 文件总行数;awk计算比值后,用%.2f格式化保留两位小数,和示例输出一致。
如果要避免文件总行数为0时的除零错误,可修改awk逻辑:
join <(grep -c "pattern" f* | sort) <(wc -l f* | grep -v total | sort) | awk '{ratio = ($3 == 0) ? 0 : $2/$3; printf "%s %.2f\n", $1, ratio}'
方案二:逐个文件遍历计算
如果需要更直观的循环逻辑,可遍历每个目标文件,分别获取数值后计算:
for file in f*; do grep_count=$(grep -c "pattern" "$file") # 用<避免wc输出文件名,只取行数 wc_count=$(wc -l < "$file") if [ "$wc_count" -eq 0 ]; then ratio=0.00 else # 用bc指定精度计算浮点比值 ratio=$(echo "scale=2; $grep_count / $wc_count" | bc) fi printf "%s %.2f\n" "$file" "$ratio" done
说明:
wc -l < "$file"仅输出行数,避免后续处理文件名的麻烦;bc的scale=2参数指定计算结果保留两位小数;- 增加了总行数为0的判断,防止除零报错。
内容的提问来源于stack exchange,提问作者jenna
相关产品推荐
相关产品推荐

