如何让 bc(1) 打印前导零?
我在 Makefile 中执行如下操作:(
echo "0.1 + 0.1" | bc
当然,在实际文件中,数字是动态的)
它打印 .2
但我希望它打印 0.2
。
我想在不诉诸 sed 的情况下执行此操作,但我似乎找不到如何让 bc 打印零。或者是 bc
无法做到这一点?
I do something like the following in a Makefile:
echo "0.1 + 0.1" | bc
(in the real file the numbers are dynamic, of course)
It prints .2
but I want it to print 0.2
.
I would like to do this without resorting to sed
but I can't seem to find how to get bc
to print the zero. Or is bc
just not able to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
您还可以使用 awk 来格式化:
或使用 awk 本身进行数学计算:
You can also resort to awk to format:
or with awk itself doing the math:
这可能对你有用:
This might work for you:
快速查看 源代码(参见
bc_out_num()
,第1461行),如果整数部分是0
。除非我错过了什么,否则此行为不依赖于可以使用命令行标志更改的参数。简短回答:不,我认为没有办法让
bc
按照您想要的方式打印数字。如果您仍想使用 bc,我认为使用 sed 没有任何问题。恕我直言,以下内容看起来并不那么可怕:
如果您真的想避免
sed
,那么 eljunior 的 a> 和 choroba 的 建议非常简洁,但它们需要依赖于值的调整以避免尾随零。这对您来说可能是问题,也可能不是问题。After a quick look at the source (see
bc_out_num()
, line 1461), I don't see an obvious way to make the leading0
get printed if the integer portion is0
. Unless I missed something, this behaviour is not dependent on a parameter which can be changed using command-line flag.Short answer: no, I don't think there's a way to make
bc
print numbers the way you want.I don't see anything wrong with using
sed
if you still want to usebc
. The following doesn't look that ghastly, IMHO:If you really want to avoid
sed
, both eljunior's and choroba's suggestions are pretty neat, but they require value-dependent tweaking to avoid trailing zeros. That may or may not be an issue for you.我在文档中找不到有关输出格式的任何内容。除了 sed,您还可以使用 printf:
I cannot find anything about output format in the documentation. Instead of sed, you can also reach for printf:
回显“$a / $b”| BC -l | sed -e 's/^-\./-0./' -e 's/^\./0./'
这应该适用于结果为
解释:
对于仅以
-.
开头的所有内容,请将-.
替换为-0。
对于仅以
开头的所有内容。
,将.
替换为0.
echo "$a / $b" | bc -l | sed -e 's/^-\./-0./' -e 's/^\./0./'
This should work for all cases where the results are:
Explanation:
For everything that only starts with
-.
, replace-.
with-0.
For everything that only starts with
.
, replace.
with0.
基于 potongs 答案 ,
对于分数结果:
请注意,负结果将无法正确显示。 Aquarius Power 有一个解决方案 为此。
Building on potongs answer,
For fractional results:
Note that negative results will not be displayed correctly. Aquarius Power has a solution for that.
这也将处理负数:
This one will also handle negative numbers:
这只使用 bc,并且适用于负数:
尝试使用:
this only uses bc, and works with negative numbers:
try it with:
这是纯粹的
bc
。它通过将表达式的length
结果与scale
进行比较来检测前导零。它适用于正数和负数。This one is pure
bc
. It detects the leading zero by comparing the result of thelength
with thescale
of the expression. It works on both positive and negative number.对于正数,它可能就像打印(字符串)零一样简单:
如果数字大于(或等于)1,则避免使用零:
如果数字可能为负数,它会变得有点复杂:
您可以定义一个函数并将其添加到库中:
For positive numbers, it may be as simple as printing (an string) zero:
avoid the zero if the number is bigger (or equal) to 1:
It gets a bit more complex if the number may be negative:
You may define a function and add it to a library:
也许,
bc
并不是现代最好的“台式计算器”。其他语言会给你更多的控制权。以下是打印 (-1.0..+1.0) 范围内的值(带前导零)的工作示例。这些示例使用bc
、AWK
和Python 3
,以及 这里字符串语法。请注意,Python 版本大约慢 10 倍,如果这很重要的话(对于大多数用途来说仍然非常快)。
使用
sh
或bc< 进行任何重要的数学运算/code> 是愚蠢的差事。现在有更好的台式计算器。例如,您可以使用 此处文档 在 Bash 脚本中嵌入并执行 Python 子例程。
输出:
Probably,
bc
isn't really the best "bench calculator" for the modern age. Other languages will give you more control. Here are working examples that print values in the range (-1.0..+1.0) with a leading zero. These examples usebc
,AWK
, andPython 3
, along with Here String syntax.Note that the Python version is about 10x slower, if that matters (still very fast for most purposes).
Doing any non-trivial math with
sh
orbc
is a fool's errand. There are much better bench calculators available nowadays. For example, you can embed and execute Python subroutines inside your Bash scripts using Here Documents.Output:
另一种简单的方法,类似于此线程此处中的一篇文章:
打印变量列表,包括前导 0 和换行符。
Another simple way, similar to one of the posts in this thread here:
Print the list of variables, including the leading 0 and the newline.
由于您的问题被标记为
[bash]
,您可以简单地计算答案并使用命令替换将其保存到变量中(例如r="$(.. .)"
),然后使用[[..]]
和=~
来测试结果中的第一个字符是否为[1- 9]
(例如[[ $r =~ ^[1-9].*$ ]]
),如果第一个字符不是,则在r
的开头添加'0'
,例如(编辑,由于 G.Man 的良好捕获...)
结果
如果结果
r
为1.0
或更大,则不为零前置,例如(作为 1-liner)和处理负值
Since you have the question tagged
[bash]
you can simply compute the answer and save it to a variable using command substitution (e.g.r="$(...)"
) and then using[[..]]
with=~
to test if the first character in the result is[1-9]
(e.g.[[ $r =~ ^[1-9].*$ ]]
), and if the first character isn't, prepend'0'
to the beginning ofr
, e.g.(edit due to good catch by G.Man...)
Result
If the result
r
is1.0
or greater, then no zero is prepended, e.g. (as a 1-liner)and negative values handled
根据 cafemike 的回答 和 Martin T. 的评论,我想出了这个解决方案。
正则表达式的解释。
对于句子开头的点
\.
^
或\|
不是数字[^0123456789]
,进行替换。\1
是\(
圆括号\)
的反向引用。如果是“句子开头”的情况,则后向引用什么都没有。
如果是“不是数字”的情况,则后向引用是点之前的一个字符。因此,这适用于负号,或空格,或任何符号或字符(只要不是 0-9)。
对于句子中的任何点,它也可以替换为 0。 因此,我添加了另一个反向引用
\。 2
它只会进行替换。如果点后跟一个数字。Based on cafemike's answer and Martin T.'s comment, i come up with this solution.
Explanation for the regular expression.
For a dot
\.
that is at the beginning of the senstence^
or\|
that is not a digit[^0123456789]
, do the replacement.\1
is a back reference of the\(
round brackets\)
.If it is the case of "beginning of the sentence, the back reference is nothing.
If it is the case of "not a digit", the back reference is the one character before the dot. Thus this works for negative sign, or a space, or any symbols or characters (as long as not 0-9).
There is a catch. For any dot within a sentence, it may be replaced with 0. as well. Thus i am adding another back reference
\2
. It will do the replacement only if the dot is followed by a digit.