0

I have a few data text files whose lines are values with their error, like these:

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

the third column is the error relativley to the second column. I would like to write a script that prints them in a more human-readable format, that is to print the value with the right number of significant digits and to print the error on the last two digist between parenthesis, like this:

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

using regular expressions to extract the numbers wouldn't work right because of difficulties of handling the dot and because it would truncate numbers rather than approximate them, so i thought that i'd rather retrieve their magnitude with printf and handle them with bc.

The code I wrote for this is as follows

#! /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

what i get is

6 90.379000(95)
40 1028.500000(44)

My code almost works, except for the appearence of those trailing zeroes.

How do I get rid of them? Just cutting them would not be good because their number is not fixed and cutting them all would give rise to errors wheter the last digit actually is a zero.

Ferdinando Randisi
  • 4,068
  • 6
  • 32
  • 43

2 Answers2

0

If using a sed command is ok for you, you can add a sed statement after your printf to remove the trailing zeros:

printf "$a %f(%.0f)\n" `echo "lenght=length($v);$v*10^($((-$dov)))" | bc -l` `echo "$verr*10^($dov)" | bc -l` | sed 's/00*(/(/'
choroba
  • 231,213
  • 25
  • 204
  • 289
Guru
  • 16,456
  • 2
  • 33
  • 46
  • Thanks, but as i pointed out at the end of my question i can't simply do that because I don't know how many of them are added. I can't just take them all away, becasue if one of the significant digits is a zero that would get stripped away as well. Or wouldn't it? – Ferdinando Randisi Oct 12 '12 at 23:50
  • it would not strip if the significant digits is a 0. – Guru Oct 13 '12 at 02:41
  • why not? I barely know any sed, but it seems to me that with that command you remove anything from 2 consecutive zeroes onward. If so, should my values contain two following zeroes as significant digits then they would all be removed. E.g., this would not work with the record `40 1008.4633 4.4179`, nor with something like `6 10.000633 0.4179`. – Ferdinando Randisi Oct 13 '12 at 13:12
0

The following code works.

#! /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 "$a\t%.${dov}f(%.1f)\n" $u $uerr>>$s
    else
    uerr=`echo "$verr*10^($dov)" | bc -l`
    printf "$a\t%.${dov}f(%.0f)\n" $u $uerr>>$s
    fi
else
    echo $a "${v}(${verr})E$ov">>$s
fi
done < $f

it prints the values formatted as I wanted. The first case tests whether it needs to express the result in exponential notation in order to get significant digits right, and the second if case tests wheter it should put a dot in the error.

I have not tested the third line of code from the bottom because I do not need it now, so be cautious because it might not work.

EDIT: I inserted two sed calls to handle scientific notation numbers.

Ferdinando Randisi
  • 4,068
  • 6
  • 32
  • 43