Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex bash+;sed:从浮点数中修剪尾随的零?_Regex_Bash_Sed_Floating Point - Fatal编程技术网

Regex bash+;sed:从浮点数中修剪尾随的零?

Regex bash+;sed:从浮点数中修剪尾随的零?,regex,bash,sed,floating-point,Regex,Bash,Sed,Floating Point,我试图从浮点数中去掉尾随的十进制零,但到目前为止运气不好 echo "3/2" | bc -l | sed s/0\{1,\}\$// 1.50000000000000000000 我希望得到1.5,但不知怎的,后面的零没有被截断。如果我显式地写0或000000等,而不是0\{1,\}I,那么它会删除输入的零,但显然我需要它是动态的 0\{1,\}有什么问题?$不能转义并引用sed模式: echo "3/2" | bc -l | sed 's/0\{1,\}$//' 1.5 为什么不直接用比

我试图从浮点数中去掉尾随的十进制零,但到目前为止运气不好

echo "3/2" | bc -l | sed s/0\{1,\}\$//
1.50000000000000000000
我希望得到
1.5
,但不知怎的,后面的零没有被截断。如果我显式地写0或000000等,而不是
0\{1,\}
I,那么它会删除输入的零,但显然我需要它是动态的


0\{1,\}
有什么问题?

$
不能转义并引用sed模式:

echo "3/2" | bc -l | sed 's/0\{1,\}$//'
1.5

为什么不直接用
比例设置所需的位数呢

$ echo "scale=1; 3/2" | bc -l 
1.5
$ echo "scale=2; 3/2" | bc -l 
1.50
$ echo "scale=5; 3/2" | bc -l 
1.50000

我建议您使用
manbc
,因为它包含许多有趣的方法来显示您的结果。

@anubhava对您的命令失败有正确的原因,但只需使用awk即可:

$ awk 'BEGIN{print 3/2}'
1.5

您可以使用
printf
进行以下操作:

printf "%.1f" $(bc -l <<< '3/2')
1.5
printf“%.1f”$(bc-l
  • 如果有小数分隔符,请删除尾随的0
  • 如果分隔符后面只有0,则删除分隔符(假设前面至少有一个数字,就像BC一样)

修剪浮点数尾随零的一种简便方法是
grep--仅匹配
选项:

$ echo 1 + 0.1340000010202010000012301000000000 | bc -l | grep -o '.*[1-9]'
1.1340000010202010000012301
-o、 --仅匹配

仅打印匹配行的匹配(非空)部分,每个部分 这种部件在单独的输出线上


这是我的看法。它删除前导零,然后如果数字中任何地方有小数,它也会删除尾随零。此表达式也适用于前面或后面有空格字符的数字(如果存在)

sed -e "s/^\s*0*//" -e "/\./ s/0*\s*$//"

这可能是一个测试用例,否则您可以更改
bc
中的
scale
参数以减少小数位数。@Etan实际上,
\{1,\}
谢谢,我将研究
man bc
,因为它对我来说很新。但是在这种特殊情况下,我不需要特定的位数,而是需要最大的精度,只需要去掉任何不必要的尾随零。尾随零对于最大精度是必要的。
1.5000
1.5
精确得多(可能介于
1.45
1.54
之间。它不回答问题,而是执行后面的请求。假设在您的回答中,
bc-l
只是示例生成器(您仍然可以获得我的投票)@NeronLeVelu yep,我要解决的是问题的核心,而不是OP在其解决方案中发现的
sed
问题。然而,对我来说,控制格式的最佳方法是使用
printf
,如图所示。@chepner我同意一般来说
1.5000
是不同的(更精确)比
1.5
,但在这个特殊情况下,我想去掉剩余的零。好的!我曾想过使用
printf
,但没有成功,因为我使用的是
printf“%f”$((3/2))
$(())
只做整数运算。这将把每个结果四舍五入到小数点后1位,而不是像OP所希望的那样去掉尾随的零。谢谢!是的,我还没有涵盖例外情况,只是在分隔符后去掉零(我不希望3500被修剪到35)或者移除分隔符本身(如果适用)。首先,我想让正则表达式工作:)但是很好的补充,thx!事实上,我不完全理解sed参数的第一部分。作为sed noob,我只熟悉使用
s//
的sed。通过mansed查看,我理解s之前的点是一个“地址”,它作为一个额外的过滤器,即
sed//
只会用替换
搜索
de>替换
对于同样匹配
过滤器的输入,是否正确?
/\./
是一个包含点的行上的模式过滤器(避免删除10的倍数上的尾随0,如25000)。仅当模式(或地址)时,才过滤、激活以下操作(或组,如果使用了
{}
)过滤器的所有部分都是兼容的。因此,是的,您是正确的
sed -e "s/^\s*0*//" -e "/\./ s/0*\s*$//"