最近的脚本因为涉及到一些计算,比方乘以80%,乘以1.2,除以80%这种的,有时候希望能得到小数,有时候希望结果是截断小数的,但是实际计算的时候还是迷迷糊糊的,所以特此整理一下。
1.首先来几个实验验证一下:
从上面这个图中可以看到,在bc的交互命令模式下:
1+2=3
1*0.8=.8 这里还是希望结果是0.8
10*1.23=12.3
1/5=0
22/5=4 整数的除法是截断的,24/5=4.8,截断之后仍然是4,有时候我们会希望四舍五入,有时候我们希望保留两位小数。
继续了解一下,会有
0.8/2 =0
1/0.8 =1
1*5/4=1
这些结果。
那我们开始解决一些疑问吧:
1.1/0.8=.8
如何得到0.8的结果?
2.1/5=0
如何得到0.2的结果?
324/5=4
如何得到5的结果(四舍五入)?
4.1/3=0
如何得到0.33的结果(保留两位小数)?
首先,bash只支持整型运算,但可以使用bc,awk和nawk工具来处理更复杂的运算。
1.scale … |bc 方式可以指定保留小数位数
[root@db22 ~]# echo "scale=2;1/5"|bc
.20
[root@db22 ~]# echo "scale=2;24/5"|bc
4.80
说明: echo命令的输出通过管道传送给bc程序。变量scale赋值为2,表示小数点后的有效位数为2。bc 来计算1除以5的值
2.awk的方式
[root@db22 ~]# echo `awk -v x=1 -v y=5 'BEGIN{printf "%.2f\n",x/y}'` 0.20
说明:通过命令行传递参数列表,gawk从该列表中获取参数值:x=2.45,y=3.123。乘法运算完成后,printf函数格式化并显示运算结果,保留小数点后两位数,并将输出赋给变量product。
2.1 printf的格式化输出
上面代码中的%.2f 被称为格式符(format specifier)。格式符由以下几部分组成:
%[flags][width][.precision]conversion
% - 5 .2 f
- %是必须的,任何格式符都由百分号开始
- flags 是可选的,详见下表
- width 是可选的,表示输出的宽度
- precision 可选的,precision 依赖于 conversion,详见下表.
- conversion 是必须的,表示如何格式化参数,详见下表
awk 支持如下转换符(conversion)。
转换符 | 描述 |
---|---|
c | ASCII 字符 (打印第一个字符) |
d | 十进制整数 |
i | 十进制整数 |
e | 浮点数科学计数法 |
E | 浮点数科学计数法 |
f | 浮点数 |
g | %e 或 %f,取决于哪个更短,删除尾部0 |
G | %E 或 %f,删除尾部0 |
u | 无符号十进制整数 |
o | 无符号八进制整数 |
x | 无符号十六进制整数(a-f for 10 to 15) |
X | 无符号十六进制整数(A-F for 10 to 15) |
%% | % |
s | 字符串 |
awk 支持如下标志(flag)
标志 | 描述 | 举例 |
---|---|---|
- | 左对齐 | [3333.33] |
空格 | 在正数之前添加空格 | [ 3333.33],[-3333.33] |
+ | 打印正负数符号 | [+3333.33],[-3333.33] |
0 | 数字前面补0 | [003333.33] |
(对于%o) | 添加前缀0 | [0515] |
(对于%x) | 添加前缀0x | [0x1bc] |
(对于%X) | 添加前缀0X | [0X1bc] |
(对于%e) | 添加小数点 | [1.000000e+01] |
(对于%E) | 添加小数点 | [1.000000E+01] |
(对于%f) | 添加小数点 | echo awk -v x=1 -v y=5 'BEGIN{printf "%#f\n",x*y}' 结果: [5.000000] |
(对于%g) | 不删除尾部0 | [10.4000] |
(对于%G) | 不删除尾部0 | [10.4000] |
awk 精度(precision)的意义
转换符 | 精度意义 |
---|---|
%d,%i,%o,%u,%x,%X | 最少数字位数,如果数字位数少于精度,添加前缀0 |
%e,%E | 最少数字位数,如果数字位数少于精度,添加后缀0 |
%f | 小数的位数 |
%g,%G | 最多数字位数 |
%s | 字符位数 |
sprintf 函数
如果你不想打印,而是想格式化一个字符串,然后把它保存到一个变量中,该怎么办呢?试一试 sprintf 函数吧。
#! /usr/bin/awk -f
BEGIN {
str=sprintf("%5.2f",33.698);
print str;
};
{};
END {};
利用已经习得的命令来解决我们在一开始提出的4个问题
那我们开始解决一些疑问吧:
1.1/0.8=.8
如何得到0.8的结果?
2.1/5=0
如何得到0.2的结果?
324/5=4
如何得到5的结果(四舍五入)?
4.1/3=0
如何得到0.33的结果(保留两位小数)?
四舍五入的这个可以在结果上+0.5来达到。
@H_472_404@参考文档: