I have this line using awk
:
$ awk '{
for (i=1;i<=NF;i ){
if ($i 0 != $i)
$i = temp[i] 0.00
temp[i]=$i 0.00
}}1'
In short, this converts every word to the last seen number of that column.
THE PROBLEM
The issue is that the decimals place of every value that comes out of $i = temp[i] 0.00
loses its decimals precision.
For example,
-ERROR -1.57 -2.02
-2.10 2.70 ERROR
-4.70 ERROR -0.52
-2.20 ERROR -0.02
-2.20 -1.50 ERROR
Turns into:
0 -1.57 -2.02
-2.10 2.70 -2.02
-4.70 2.7 -0.52
-2.20 2.7 -0.02
-2.20 -1.50 -0.02
2.70
would become 2.7
and so every word that directly follows 2.70
would not be turned into 2.70
, but instead into 2.7
. How can you force awk to save a float value to a set amount of decimal places?
Obviously, 0.00
didn't help.
CodePudding user response:
Refrain from performing math on the values which in turn disables awk
from making decisions on how many digits of accuracy to maintain; instead, just save each value as is (effectively save as a string).
Consider:
$ printf "1 1.1 1.02 1.003 1.0004 1.00005\na b c d e f\n"
1 1.1 1.02 1.003 1.0004 1.00005
a b c d e f
A few tweaks to OP's current awk
code:
$ printf "1 1.1 1.02 1.003 1.0004 1.00005\na b c d e f\n" | awk '
{ for (i=1;i<=NF;i ){
if ($i 0 != $i)
$i = (i in temp ? temp[i] : 0)
temp[i]=$i
}
} 1'
1 1.1 1.02 1.003 1.0004 1.00005
1 1.1 1.02 1.003 1.0004 1.00005
Coming back to OP's sample data ...
Adding some more lines to the sample data set:
$ cat sample.dat
-ERROR -1.57 -2.02
-2.10 2.70 ERROR
-4.70 ERROR -0.52
-2.20 ERROR -0.02
-2.20 -1.50 ERROR
-3.333 0.1234 -0.02
ERROR ERROR ERROR
-2.10 2.70 ERROR
-4.70 ERROR -0.52
Running the modified awk
code:
awk '
{ for (i=1;i<=NF;i ){
if ($i 0 != $i)
$i = (i in temp ? temp[i] : 0)
temp[i]=$i
}
}1' sample.dat
This generates:
0 -1.57 -2.02
-2.10 2.70 -2.02
-4.70 2.70 -0.52
-2.20 2.70 -0.02
-2.20 -1.50 -0.02
-3.333 0.1234 -0.02
-3.333 0.1234 -0.02
-2.10 2.70 -0.02
-4.70 2.70 -0.52
If this doesn't address the issue then we'll need to see more sample data that more accurately reproduces the issue.