Cutting numbers into a specific decimals

You can use sed:

sed -E 's/([0-9]+\.[0-9]{5})[0-9]*/\1/g' file

Add -i option to add file in place.


If you don't mind the integers also being converted to floating point, you could use numfmt:

$ numfmt --field=1- --format=%.5f --invalid=ignore < file
1.00000
            12.23487              0.00000              0.00000
             0.00000              3.03201              0.00000
            -1.37521              0.00000              5.61831
   Ga    O
8.00000 12.00000
Direct
         0.59003             0.50000             0.79426
         0.40998             0.50000             0.20575
         0.90998             0.00000             0.20575
         0.09003             0.00000             0.79426
         0.65889             0.00000             0.31409

Explanation

  • --field=1-

    This option tells numfmt which occurrences need to be replaced. 1- in this case means from the first occurrence until the end of the line.

  • --format=%.5f

    This option tells numfmt how to format the output numbers. %.5f in this case means format them as floating numbers with 5 decimal digits.

  • --invalid=ignore

    This option tells numfmt what to do in case it was not able to format a number. ignore in this case just ignores the problematic input and carries on with next input.

By default, numfmt applies IEEE 754 rounding rules - if you want simple truncation, you can add --round=towards-zero. The complete list of rounding options is up, down, from-zero (default), towards-zero, nearest.

You can view manpage for more details:

  • http://manpages.ubuntu.com/manpages/bionic/man1/numfmt.1.html

If you want IEEE 754 rounding but want it to apply strictly to floating point numbers with more than 5 digits after the point, then I'd suggest using perl - it can match regular expressions, like sed, but allows you to apply a sprintf expression to the captured pattern:

perl -pe 's/[+-]?\d*[.]\d{5,}/sprintf "%.5f", $&/ge' file

Like GNU sed, perl can modify the file in-place by adding the -i option.


With GNU sed:

sed -E 's/\.([0-9]{5})[0-9]*/.\1/g' file

Output:

1.0
       12.23486         0.00000         0.00000
        0.00000         3.03200         0.00000
       -1.37520         0.00000         5.61830
   Ga    O
    8   12
Direct
     0.59002         0.50000         0.79425
     0.40997         0.50000         0.20574
     0.90997         0.00000         0.20574
     0.09002        -0.00000         0.79425
     0.65888         0.00000         0.31408

Use extended regular expressions with -E:

sed -E


Match the pattern .<five digits><n digits> with \.([0-9]{5})[0-9]*. Capture the 5 digits following the dot . with ([0-9]{5})

s/\.([0-9]{5})[0-9]*/

Replace the match with the dot . and the captured pattern:

/.\1/

Tags:

Command Line