Question

I want to take the following input

Average Box 1: 0.520522 Std. Dev. Box 1: 0.00297154

...print the first number (the average) rounded to a certain digit, where that digit is defined by the first significant digit of the ROUNDED std. dev.

e.g. --> Rounded Std 0.003 <-- (so third digit)
--> 0.521 (in this case)

To give a border case:
Average Box 1: 0.52156 Std. Dev. Box 1: 0.0099675
--> Rounded Std 0.01 <-- (so second digit)
--> 0.52 (in this case)

Can I do this all via some manner of Awk magic? If so, how? If not, what COULD I use to do it (my last resort is a C program, but shell programs seem more efficient)?

(This is for data extraction on a research project, aka /nothomework.)

Was it helpful?

Solution

Here is one way with awk.

Assuming infile with content:

Average Box 1: 0.520522 Std. Dev. Box 1: 0.00297154
Average Box 1: 0.52156 Std. Dev. Box 1: 0.0099675

Run following script:

awk '
    ## For every line...
    { 
        ## Get number in form "[-]d.dddddde[+-]dd."
        num = sprintf( "%e", $NF ); 
        e = num;

        ## Get exponent.
        sub( /^.*e-/, "", e ); 

        ## Get the decimal number without zero digits at the beginning.
        sub( /e.*$/, "", num ); 

        ## Round the number.
        num = int(num+0.5);

        ## Apply the exponent to this no-fractional rounded number 
        for ( i = 1; i <= int(e); i++ ) {
            num = num / 10;
        }

        ## Get the position of the digit in the decimal number.
        ## Examples:
        ## If number is 0.003 the position will be two below its length
        ## Same if number is 0.01,
        ## etc.
        num = length(num) - 2;

        ## Print rounded floating point number
        printf( "%." num "f\n", $4 ) 
    }
' infile

That yields:

0.521
0.52
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top