Awk Rounding of Value Field Based on Significance of Second Rounded Field
-
12-12-2019 - |
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.)
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