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 followss/(\.\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 thene
then the second groupg
globally - don't stop at the first substitution in each line, but process all possible hits
- substitute (
print
print the linesample
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