[转载]使用awk进行数字计算,保留指定位小数

对于在Shell中进行数字的计算,其实方法有很多,但是常用的方法都有其弱点:

1、bc

bc应该是最常用的Linux中计算器了,简单方便,支持浮点。

[[email protected] ~]$ echo 1+2 |bc
3
[[email protected] ~]$ echo 5.5*3.3 |bc
18.1
[[email protected] ~]$ echo 5/3 |bc
1
[[email protected] ~]$ echo "scale=2;5/3" |bc
1.66

看似在简单计算时候完美的bc,其实也有一个让我抓狂的地方,当然有可能有办法可以解决,只是我不知道而已,那就是…… 在出现整数部分为0的时候,这个0是不显示出来的,例如0.5只会显示为.5,情何以堪!

[[email protected] ~]$ echo "scale=2;1/2" |bc
.50
[[email protected] ~]$ echo "scale=4;17/20" |bc    
.8500

而且…… 像一些第三方基于Linux底层的产品,为了系统本身的稳定和轻便,默认是不带bc的,例如……F5

2、expr

不支持浮点计算,即不支持小数,所以也常被用来判断变量内容或者结果是不是非0整数(expr 0的echo $?不是0)。

[[email protected] ~]$ expr 3 + 5
8
[[email protected] ~]$ expr 10 / 2
5
[[email protected] ~]$ expr 10 / 3
3
[[email protected] ~]$ expr 7 / 2
3
[[email protected] ~]$ expr 0
0
[[email protected] ~]$ echo $?
1

3、$(())

不支持浮点计算。

[[email protected] ~]$ echo $((8+3))
11
[[email protected] ~]$ echo $((10/2))
5
[[email protected] ~]$ echo $((10/3))
3
[[email protected] ~]$ echo $((1.5*3))
-bash: 1.5*3: 语法错误: 无效的算术运算符 (错误符号是 ".5*3")

4、let

不仅不支持浮点计算,而且还只能赋值,不能直接输出。

[[email protected] ~]$ let a=1+2
[[email protected] ~]$ echo $a
3
[[email protected] ~]$ let b=10/5
[[email protected] ~]$ echo $b
2
[[email protected] ~]$ let c=1.5*3
-bash: let: c=1.5*3: 语法错误: 无效的算术运算符 (错误符号是 ".5*3")
[[email protected] ~]$ echo $c
[[email protected] ~]$

上面的几种方式,是我之前常用的方式,但是现在我在shell脚本中有一个需求,在计算数字时,会出现浮点计算,也会出现0-1之间的小数,前面的几个方式恐怕都无法满足。

这里,我使用的是awk计算:

[[email protected] ~]$ echo | awk ‘{print 17/20}‘
0.85
[[email protected] ~]$ echo | awk ‘{print 1.5*3}‘
4.5

看上去还可以,那么进一步,我需要带变量:

[[email protected] ~]$ A=5
[[email protected] ~]$ B=16
[[email protected] ~]$ C=29
[[email protected] ~]$ echo | awk ‘{print $A/$B}‘
awk: cmd. line:1: (FILENAME=- FNR=1) fatal: division by zero attempted
[[email protected] ~]$ echo | awk "{print $A/$B}" 
0.3125
[[email protected] ~]$ echo | awk "{print $C*$A}"
145
[[email protected] ~]$ echo | awk "{print $C*$A/$B}"
9.0625

看上去也还可以,只是注意awk后的单引号需要变为双引号。

再进一步,上面最后一次的计算,小数点后面出现了4位,我希望只保留两位,不然看着太乱。但是没有找到这里可以保留小数位的参数和方法,于是我尝试一下将print换为printf:

[[email protected] ~]$ echo | awk ‘{print 10/3}‘
3.33333
[[email protected] ~]$ echo | awk ‘{printf ("%.2f\n",10/3)}‘ 
3.33

将print换成printf,就可以有方法进行小数位的限制了,看似不错,但是……

[[email protected] ~]$ A=5
[[email protected] ~]$ B=16
[[email protected] ~]$ C=29
[[email protected] ~]$ echo | awk ‘{printf ("%.2f\n",$A/$B)}‘
awk: cmd. line:1: (FILENAME=- FNR=1) fatal: division by zero attempted
[[email protected] ~]$ echo | awk "{printf ("%.2f\n",$A/$B)}" 
awk: cmd. line:1: {printf (%.2fn,5/16)}
awk: cmd. line:1:          ^ syntax error
[[email protected] ~]$ echo | awk "{printf (‘%.2f\n‘,$A/$B)}"
awk: cmd. line:1: {printf (‘%.2f\n‘,5/16)}
awk: cmd. line:1:          ^ invalid char ‘‘‘ in expression
awk: cmd. line:1: {printf (‘%.2f\n‘,5/16)}
awk: cmd. line:1:          ^ syntax error

使用变量参与计算的话,会发现一直在报错,这种情况,建议先在前面的echo中将需要使用的变量输出出来,再进行调用。

[[email protected] ~]$ A=5
[[email protected] ~]$ B=16
[[email protected] ~]$ C=29
[[email protected] ~]$ D=6
[[email protected] ~]$ echo "$A $B $C $D" | awk ‘{printf ("%.2f\n",$1*$2/$3-$4)}‘
-3.24
[[email protected] ~]$ echo "$A $B $C $D" | awk ‘{printf ("%.2f\n",$1/$4)}‘      
0.83
[[email protected] ~]$ echo "$A $B $C $D" | awk ‘{printf ("%.3f\n",$1/$4)}‘
0.833

注意,使用printf的时候,awk后面必须是单引号,双引号会报错。虽然这种方法麻烦一些,但是起码可以实现我的需求,如果有朋友知道bc计算的结果为0-1之间的小数时,怎么让他显示出来前面的0. ,欢迎留言,不喜勿喷。

补充,有的时候在计算数字后,会发现你的结果已经不是正常的一串数字了,而是在其中穿插了字母e或者E,这是因为数字过大,系统采用了类似于科学计数法的表达方式(正确叫法不确定,勿喷),但是如果直接使用这一串内容再去计算的话,会报错,系统会认为这是字符串而非数字,这种情况也可以使用awk进行转变,其实准确的说是printf的功能。

[[email protected] uncomp]$ echo "6.8923e+08/100" |bc
(standard_in) 1: syntax error
[[email protected] uncomp]$ echo "6.8923e+08" | awk ‘{printf ("%.0f\n",$1)}‘
689230000
时间: 2024-11-09 14:39:26

[转载]使用awk进行数字计算,保留指定位小数的相关文章

强制保留指定位小数

//强制保留指定位小数 function getFloatNum(num, index) { if(typeof num == "undefind" || num == null || num == "" || isNaN(num)) return num; if(!index) index = 2; var _num = parseFloat(num).toFixed(parseInt(index)); return _num; }; console.log(ge

使用awk进行数字计算,保留指定位小数

对于在Shell中进行数字的计算,其实方法有很多,但是常用的方法都有其弱点: 1.bc bc应该是最常用的Linux中计算器了,简单方便,支持浮点. [[email protected] ~]$ echo 1+2 |bc 3 [[email protected] ~]$ echo 5.5*3.3 |bc 18.1 [[email protected] ~]$ echo 5/3 |bc 1 [[email protected] ~]$ echo "scale=2;5/3" |bc 1.6

数字四舍五入保留两位小数

http://www.cnblogs.com/fanyong/archive/2013/05/30/chinese_round.html C#中的Math.Round()并不是使用的"四舍五入"法.其实在VB.VBScript.C#.J#.T-SQL中Round函数都是采用Banker's rounding(银行家算法),即:四舍六入五取偶.事实上这也是IEEE的规范,因此所有符合IEEE标准的语言都应该采用这样的算法. .NET 2.0 开始,Math.Round 方法提供了一个枚举

MongoDB数字类型保留2位小数

print(((0.1+0.1+0.1+0.1+0.1) /5).toFixed(2))

java读写文件及保留指定位小数

1)先上代码: 1 public static void main(String[] args)throws IOException{ 2 3 4 double[][] B=new double[1043][21025]; 5 double[][] transformB=new double[21025][1043]; 6 7 8 String filename="/home/hadoop/srcData/B.txt"; 9 final LineIterator it = FileUt

Java保留两位小数的几种做法

1.  String类型数字始终保留两位小数 public static void main(String[] args) {   DecimalFormat format = new DecimalFormat("0.00");  String abc ="100.456";  String a = format.format(new BigDecimal(abc)); System.out.println(a); } 2. 另外几种办法 原文 http://mo

BigDecimal的用法详解(保留两位小数,四舍五入,数字格式化,科学计数法转数字,数字里的逗号处理)

转自:https://blog.csdn.net/ochangwen/article/details/51531866 一.简介 Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更小的数进行运算和处理.float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal.BigDecimal所创建的是对象,我们不

String转换成float并且保留两位小数,购物车计算价格

方法1: 用DecimalFormat 返回的是String格式的.该类对十进制进行全面的封装.像%号,千分位,小数精度.科学计算. float perPrice=Float.parseFloat(textView_price_shopCar.getText().toString()) * count;//String类型转换成float类型 DecimalFormat decimalFormat=new DecimalFormat(".00");//构造方法的字符格式这里如果小数不足

sql server数据库实现保留指定位数小数的函数

有时候需要对一个特定的含有小数点的数字保留指定位数,比如"123.123600". 在数据库中以函数的形式实现如下: USE [数据库名称] GO /****** Object: UserDefinedFunction [dbo].[AvgLimit] Script Date: 2016/12/29 11:30:44 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO create function [dbo].[AvgLi