Manipulate scientific format without the "e"

Is this output correct?

 1.056000e+0 5.000000e-1 2.454400e-3 2.914800e-2 8.141500e-6
 2.043430e+1 5.000000e-1 2.750500e-3 2.698100e-2-2.034300e-4
 3.829842e+1 5.000000e-1 1.969923e-2 2.211364e-2 9.499900e-6
 4.168521e+1 5.000000e-1 1.601262e-2 3.030919e-2-3.372000e-6
 6.661784e+1 5.000000e-1 5.250575e-2 3.443669e-2 2.585500e-5
 7.278104e+1 5.000000e-1 2.137055e-2 2.601701e-2 8.999800e-5
 9.077287e+1 5.000000e-1 1.320498e-2 2.961020e-2-1.011600e-5
 9.248130e+1 5.000000e-1 3.069610e-3 2.786329e-2-6.317000e-5
 1.049935e+2 5.000000e-1 4.218794e-2 3.321955e-2-5.097000e-6
 1.216283e+2 5.000000e-1 1.432105e-2 3.077165e-2 4.300300e-5

Code:

perl -lne 's/(\.\d+)(\+|\-)/\1e\2/g; print' sample

Explanation:

  • -lne take care of line endings, process each input line, execute the code that follows

  • s/(\.\d+)(\+|\-)/\1e\2/g:

    • substitute (s)
    • (.\d+)(\+|\-) find two groups of (a dot and numbers) and (a plus or minus)
    • \1e\2 substitute them with the first group then e then the second group
    • g globally - don't stop at the first substitution in each line, but process all possible hits
  • print print the line

  • sample input file

This one adds space if it's missing. In fact it puts space between the numbers regardless. Ie. if there were two spaces in some case, there would be only one in the output.

perl -lne 's/(\.\d+)(\+|\-)(\d+)(\s*)/\1e\2\3 /g; print' sample

Most of it is similar to the previous one. The new thing is the (\d+) group nr 3 and the (\s*) group nr 4. * here means optional. In the substitution no \4 is used. There's a space instead.

The output is this:

 1.056000e+0 5.000000e-1 2.454400e-3 2.914800e-2 8.141500e-6 
 2.043430e+1 5.000000e-1 2.750500e-3 2.698100e-2 -2.034300e-4 
 3.829842e+1 5.000000e-1 1.969923e-2 2.211364e-2 9.499900e-6 
 4.168521e+1 5.000000e-1 1.601262e-2 3.030919e-2 -3.372000e-6 
 6.661784e+1 5.000000e-1 5.250575e-2 3.443669e-2 2.585500e-5 
 7.278104e+1 5.000000e-1 2.137055e-2 2.601701e-2 8.999800e-5 
 9.077287e+1 5.000000e-1 1.320498e-2 2.961020e-2 -1.011600e-5 
 9.248130e+1 5.000000e-1 3.069610e-3 2.786329e-2 -6.317000e-5 
 1.049935e+2 5.000000e-1 4.218794e-2 3.321955e-2 -5.097000e-6 
 1.216283e+2 5.000000e-1 1.432105e-2 3.077165e-2 4.300300e-5 

You could also use sed, e.g.:

<infile sed -E 's/([0-9])([+-])([0-9])/\1e\2\3/g' | awk '{ print $1 + 0 }'

However, this does not take into account that the columns in OP's listing are sometimes not separated. Here is a workaround with appropriate precision:

<infile sed -E 's/.{11}/& /g'       |
sed -E 's/([0-9])([+-])/\1e\2/g'    |
gawk '{ print $1 + 0 }' OFMT='%.7g'

Output:

1.056
20.4343
38.29842
41.68521
66.61784
72.78104
90.77287
92.4813
104.9935
121.6283