如何将情侣值/错误从值+错误格式更改为值(错误)格式

  • 本文关键字:错误 格式 情侣 bash printf numeric bc
  • 更新时间 :
  • 英文 :


我有一些数据文本文件,它们的行是带错误的值,比如:

...
6  90.3785794742981 0.0952997386139722
40 1028.46336161948 4.41798447319325
...

第三列是相对于第二列的错误。我想写一个脚本,以更便于人类阅读的格式打印它们,也就是说,打印具有正确有效位数的值,并在括号之间的最后两个数字列表上打印错误,如下所示:

...
6  90.379(95)
40 1028.5(4.4)
...

使用正则表达式提取数字是不正确的,因为处理点很困难,而且它会截断数字而不是近似数字,所以我想我宁愿用printf检索它们的大小,用bc处理它们。

我为此编写的代码如下

#! /bin/bash
while read a v verr
do
ov=`printf %e $v`
ov=${ov/*e/}
overr=`printf "%e" $verr`
overr=${overr/*e/}
dov=$((1-$overr))
v=`echo "scale=0;$v*10^($dov)" | bc -l`
v=`printf %.0f $v`
printf "$a %f(%.0f)n" `echo "lenght=length($v);$v*10^($((-$dov)))" | bc -l` `echo "$verr*10^($dov)" | bc -l`
done < myfile.txt

我得到的是

6 90.379000(95)
40 1028.500000(44)

我的代码几乎可以工作,除了那些尾随零的出现。

我该如何摆脱它们?仅仅切割它们是不好的,因为它们的数字不是固定的,如果最后一个数字实际上是零,那么将它们全部切割会导致错误。

以下代码有效。

#! /bin/bash
while read a v verr
do
ov=`printf %e $v`
ov=${ov/*e/}
overr=`printf %e $verr`
overr=${overr/*e/}
dov=$((1-$overr))
v=`echo "scale=0;$v*10^($dov)" | bc -l`
v=`printf %.0f $v`
if [ $dov -gt 0 ]; then
# remember bc doesn't understand numbers in scientific notation,
# therefore we need to convert such numbers in regular notation.
u=`echo ${u} | sed 's/[eE]/\*10\^/' | sed 's/+//'`
verr=`echo ${verr} | sed 's/[eE]/\*10\^/' | sed 's/+//'`
u=`echo "$v*10^($((-$dov)))" | bc -l`
if [ $overr -eq 0 ]; then
uerr=`echo "$verr*10^($dov - 1)" | bc -l`
printf "$at%.${dov}f(%.1f)n" $u $uerr>>$s
else
uerr=`echo "$verr*10^($dov)" | bc -l`
printf "$at%.${dov}f(%.0f)n" $u $uerr>>$s
fi
else
echo $a "${v}(${verr})E$ov">>$s
fi
done < $f

它打印出我想要的格式化值。第一种情况测试它是否需要用指数表示法来表示结果,以获得正确的有效数字,第二种情况测试是否应该在错误中加一个点。

我还没有测试从底部开始的第三行代码,因为我现在不需要它,所以要小心,因为它可能不起作用。

编辑:我插入了两个sed调用来处理科学记数法数字。

如果您可以使用sed命令,您可以在printf之后添加一条sed语句来删除后面的零:

printf "$a %f(%.0f)n" `echo "lenght=length($v);$v*10^($((-$dov)))" | bc -l` `echo "$verr*10^($dov)" | bc -l` | sed 's/00*(/(/'

相关内容

  • 没有找到相关文章

最新更新