bash 如何让 bc(1) 打印前导零?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8402181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:17:56  来源:igfitidea点击:

How do I get bc(1) to print the leading zero?

bashunixbc

提问by rwos

I do something like the following in a Makefile:

我在 Makefile 中执行以下操作:

echo "0.1 + 0.1" | bc

(in the real file the numbers are dynamic, of course)

(当然,在真实文件中,数字是动态的)

It prints .2but I want it to print 0.2.

它打印,.2但我希望它打印0.2

I would like to do this without resorting to sedbut I can't seem to find how to get bcto print the zero. Or is bcjust not able to do this?

我想不诉诸于这样做,sed但我似乎无法找到如何bc打印零。或者bc只是无法做到这一点?

采纳答案by Elias Dorneles

You can also resort to awk to format:

您还可以使用 awk 来格式化:

 echo "0.1 + 0.1" | bc | awk '{printf "%f", 
 echo "0.1 0.1" | awk '{printf "%f",  + }'
}'

or with awk itself doing the math:

或者用 awk 自己做数学:

echo "x=0.1 + 0.1; if(x<1) print 0; x" | bc

回答by potong

This might work for you:

这可能对你有用:

[me@home]$ echo "0.1 + 0.1" | bc | sed 's/^\./0./'
0.2

回答by Shawn Chin

After a quick look at the source(see bc_out_num(), line 1461), I don't see an obvious way to make the leading 0get printed if the integer portion is 0. Unless I missed something, this behaviour is not dependent on a parameter which can be changed using command-line flag.

快速查看源代码后(请参阅bc_out_num()第 1461 行),0如果整数部分是0. 除非我遗漏了什么,否则这种行为不依赖于可以使用命令行标志更改的参数。

Short answer:no, I don't think there's a way to make bcprint numbers the way you want.

简短回答:不,我认为没有办法bc按照您想要的方式打印数字。

I don't see anything wrong with using sedif you still want to use bc. The following doesn't look that ghastly, IMHO:

我看不出什么毛病,使用sed,如果你仍然想使用bc。恕我直言,以下内容看起来并不那么可怕:

printf '%3.1f\n' $(bc<<<0.1+0.1)

If you really want to avoid sed, both eljunior'sand choroba'ssuggestions are pretty neat, but they require value-dependent tweaking to avoid trailing zeros. That may or may not be an issue for you.

如果你真的想避免sedeljuniorchoroba 的建议都非常简洁,但它们需要依赖于值的调整以避免尾随零。这对您来说可能是也可能不是问题。

回答by choroba

I cannot find anything about output format in the documentation. Instead of sed, you can also reach for printf:

我在文档中找不到任何关于输出格式的信息。除了 sed,您还可以使用 printf:

echo "0.1 - 0.3" | bc | sed -r 's/^(-?)\././'

回答by user3420895

This one will also handle negative numbers:

这也将处理负数:

$ 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'

回答by gomibako

$ echo '"0";0.1+0.1' | bc
0.2

This one is pure bc. It detects the leading zero by comparing the result of the lengthwith the scaleof the expression. It works on both positive and negative number.

这个是纯的bc。它通过将 的结果lengthscale表达式的 进行比较来检测前导零。它适用于正数和负数。

回答by Isaac

For positive numbers, it may be as simple as printing (an string) zero:

对于正数,它可能就像打印(一个字符串)零一样简单:

$ echo 'x=0.1+0.1;  if(x<1){"0"};  x' | bc
0.2

avoid the zero if the number is bigger (or equal) to 1:

如果数字大于(或等于)1,则避免使用零:

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

It gets a bit more complex if the number may be negative:

如果数字可能是负数,它会变得更复杂:

$ 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

You may define a function and add it to a library:

您可以定义一个函数并将其添加到库中:

#!/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)")
   }

回答by cafemike

echo "$a / $b" | bc -l | sed -e 's/^-\./-0./' -e 's/^\./0./'

echo "$a / $b" | bc -l | sed -e 's/^-\./-0./' -e 's/^\./0./'

This should work for all cases where the results are:

这应该适用于结果为的所有情况:

  • "-.123"
  • ".123"
  • "-1.23"
  • "1.23"
  • “-.123”
  • “.123”
  • “-1.23”
  • “1.23”

Explanation:

解释:

  1. For everything that only starts with -., replace -.with -0.

  2. For everything that only starts with ., replace .with 0.

  1. 对于仅以 开头的所有内容-.,替换-.-0.

  2. 对于仅以 开头的所有内容.,替换.0.

回答by nobar

Probably, bcisn'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 use bc, AWK, and Python 3.

可能,bc并不是现代最好的“台式计算器”。其他语言会给你更多的控制。以下是打印范围 (-1.0..+1.0) 中带有前导零的值的工作示例。这些示例使用bcAWKPython 3

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";

Note that the Python version is about 10x slower, if that matters.

请注意,如果这很重要,Python 版本会慢 10 倍左右。

回答by Aquarius Power

this only uses bc, and works with negative numbers:

这仅使用 bc,并适用于负数:

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

try it with:

试试看:

##代码##