我在 Makefile 中执行以下操作:
echo "0.1 + 0.1" | bc
(在真实文件中,数字当然是动态的)
它打印.2
,但我希望它打印0.2
。
我想这样做而不诉诸于,sed
但我似乎无法找到如何bc
打印零。或者bc
只是无法做到这一点?
你也可以使用 awk 来格式化:
echo "0.1 + 0.1" | bc | awk '{printf "%f", $0}'
或者用 awk 自己做数学:
echo "0.1 0.1" | awk '{printf "%f", $1 + $2}'
这可能对您有用:
echo "x=0.1 + 0.1; if(x<1) print 0; x" | bc
在快速查看源代码后(请参阅bc_out_num()
第 1461 行),0
如果整数部分是0
. 除非我错过了什么,否则此行为不依赖于可以使用命令行标志更改的参数。
简短的回答:不,我认为没有办法bc
按照您想要的方式制作打印数字。
sed
如果您仍然想使用,我认为使用没有任何问题bc
。以下看起来并不可怕,恕我直言:
[me@home]$ echo "0.1 + 0.1" | bc | sed 's/^\./0./'
0.2
如果你真的想避免sed
,eljunior和choroba 的建议都非常简洁,但它们需要依赖于值的调整以避免尾随零。这对你来说可能是也可能不是问题。
我在文档中找不到任何关于输出格式的信息。除了 sed,您还可以使用 printf:
printf '%3.1f\n' $(bc<<<0.1+0.1)
echo "$a / $b" | bc -l | sed -e 's/^-\./-0./' -e 's/^\./0./'
这应该适用于结果为:
解释:
对于仅以 开头的所有内容-.
,请替换-.
为-0.
对于仅以 开头的所有内容.
,请替换.
为0.
这也将处理负数:
echo "0.1 - 0.3" | bc | sed -r 's/^(-?)\./\10./'
$ bc -l <<< 'x=-1/2; if (length (x) == scale (x) && x != 0) { if (x < 0) print "-",0,-x else print 0,x } else print x'
这个是纯的bc
。length
它通过将表达式的结果与表达式的结果进行比较来检测前导零scale
。它适用于正数和负数。
对于正数,它可能就像打印(字符串)零一样简单:
$ echo '"0";0.1+0.1' | bc
0.2
如果数字大于(或等于)1,请避免使用零:
$ echo 'x=0.1+0.1; if(x<1){"0"}; x' | bc
0.2
如果数字可能是负数,它会变得有点复杂:
echo 'x= 0.3 - 0.5 ; s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1) {"0"};x' | bc
-0.2
您可以定义一个函数并将其添加到库中:
$ echo 'define leadzero(x){auto s;
s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1){"0"};
return(x)};
leadzero(2.1-12.4)' | bc
-10.3
$ echo 'define leadzero(x){auto s;
s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1){"0"};
return(x)};
leadzero(0.1-0.4)' | bc
-0.3
可能,bc
它并不是现代最好的“台式计算器”。其他语言会给你更多的控制。以下是打印范围 (-1.0..+1.0) 中的值并带有前导零的工作示例。这些示例使用bc
,AWK
和Python 3
, 以及Here String语法。
#!/bin/bash
echo "using bc"
time for (( i=-2; i<=+2; i++ ))
{
echo $(bc<<<"scale=1; x=$i/2; if (x==0||x<=-1||x>=1) { print x } else { if (x<0) { print \"-0\";-x } else { print \"0\";x } } ")
}
echo
echo "using awk"
time for (( i=-2; i<=+2; i++ ))
{
echo $(echo|awk "{printf \"%.1f\",$i/2}")
}
echo
echo "using Python"
time for (( i=-2; i<=+2; i++ ))
{
echo $(python3<<<"print($i/2)")
}
请注意,如果这很重要,Python 版本大约慢了 10 倍(对于大多数用途来说仍然非常快)。
sh
用or做任何重要的数学运算bc
都是徒劳的。现在有更好的台式计算器。例如,您可以使用Here Documents在 Bash 脚本中嵌入和执行 Python 子例程。
function mathformatdemo {
python3<<SCRIPT
import sys
from math import *
x=${1} ## capture the parameter from the shell
if -1<=x<=+1:
#print("debug: "+str(x),file=sys.stderr)
y=2*asin(x)
print("2*asin({:2.0f})={:+6.2f}".format(x,y))
else: print("domain err")
SCRIPT
}
echo "using Python via Here-doc"
time for (( i=-2; i<=+2; i++ ))
{
echo $(mathformatdemo $i)
}
输出:
using Python via Here-doc
domain err
2*asin(-1)= -3.14
2*asin( 0)= +0.00
2*asin( 1)= +3.14
domain err
这仅使用 bc,并且适用于负数:
bc <<< "x=-.1; if(x==0) print \"0.0\" else if(x>0 && x<1) print 0,x else if(x>-1 && x<0) print \"-0\",-x else print x";
试试看:
for y in "0" "0.1" "-0.1" "1.1" "-1.1"; do
bc <<< "x=$y; if(x==0) print \"0.0\" else if(x>0 && x<1) print 0,x else if(x>-1 && x<0) print \"-0\",-x else print x";
echo;
done