如何在BASH的if条件语句中比较浮点数?脚本报错求助
Bash浮点数比较错误的解决与脚本优化
问题原因
你遇到的语法错误是因为Bash的(( ))算术结构仅支持整数运算,无法处理带小数点的浮点数。当传入45.1234567这类值时,Bash会把小数点识别为无效运算符,从而触发报错。
快速修复:替换浮点数比较方式
把原脚本中的浮点数比较代码:
if (( ${Numer_1} -ge ${Numer_2} ));
替换为以下两种方式之一:
方式1:用bc做比较
bc支持浮点数运算,条件成立时返回1,不成立返回0,再通过(( ))判断这个整数结果:
if (( $(echo "$Numer_1 >= $Numer_2" | bc -l) )); then
方式2:用awk做比较
通过awk的BEGIN块执行比较,根据结果返回对应退出码:
if awk -v a="$Numer_1" -v b="$Numer_2" 'BEGIN{exit !(a >= b)}'; then
高效优化:重构整个脚本
原脚本多次循环调用awk读取单行,还生成大量临时文件,效率极低。推荐用纯awk一次性完成所有逻辑,无需临时文件,代码更简洁:
#!/bin/bash # 直接生成矩阵文件,无需临时文件 awk '{ # 把所有数值存入数组 nums[NR] = $0 } END { total = NR for (i = 1; i <= total; i++) { line = "" for (j = 1; j <= total; j++) { # 计算比值(取较大值除以较小值) if (nums[i] >= nums[j]) { ratio = nums[i] / nums[j] } else { ratio = nums[j] / nums[i] } # 格式化输出精度,拼接行内容 line = line sprintf("%.7f", ratio) (j == total ? "" : ",") } # 输出一行矩阵内容 print line } }' "$1" > N_Matrix.csv
优化优势
- 仅启动一次awk进程,比原脚本多次调用awk效率提升数倍
- 直接生成CSV格式,省去
paste和删除临时文件的步骤 - 用
sprintf控制输出精度(这里保留7位小数,与输入格式一致),结果格式更统一
原问题相关信息
报错信息
line 10: ((: 45.1234567 -ge 45.1234567 : syntax error: invalid arithmetic operator (error token is ".1234567 -ge 45.1234567 ")
原脚本
#!/bin/bash rm N_Matrix.csv Lineas=`wc -l $1| awk '{print $1}'` for (( i = 1 ; i <= Lineas ; i++ )); do Numer_1=`awk -vvar=$i 'NR==var' $1` for (( j = 1 ; j <= Lineas ; j++ )); do Numer_2=`awk -vvar=$j 'NR==var' $1` if (( ${Numer_1} -ge ${Numer_2} )); then Descriptor=`echo "(($Numer_1)/($Numer_2))" | bc -l` else Descriptor=`echo "(($Numer_2)/($Numer_1))" | bc -l` fi echo $Descriptor >> $i.txt done done paste {1..29}.txt > N_Matrix.csv rm *.txt
输入文件内容
10.1234567 20.1234567 30.1234567 40.1234567 15.1234567 25.1234567 35.1234567 45.1234567
内容的提问来源于stack exchange,提问作者Another.Chemist
相关产品推荐
相关产品推荐

