将数字分解为特定的小数

将数字分解为特定的小数

我想将文件中的所有数字截断到小数点后五位。例如,我有这个文件:

Ga O # 83645, Ga2O3                     
1.0
       12.2348604202         0.0000000000         0.0000000000
        0.0000000000         3.0320000648         0.0000000000
       -1.3752052829         0.0000000000         5.6183021388
   Ga    O
    8   12
Direct
     0.590021042         0.500000000         0.794251030
     0.409978979         0.500000000         0.205748985
     0.909978943         0.000000000         0.205749006
     0.090021023        -0.000000000         0.794251030
     0.658887031         0.000000000         0.314083014

因此,我想要拥有相同的文件,但仅包含 5 位小数的数字。

答案1

如果您不介意将整数也转换为浮点数,则可以使用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

解释

  • --field=1-

    该选项告诉numfmt需要替换哪些出现的内容。1-在本例中意味着从第一次出现直到行尾。

  • --format=%.5f

    此选项告诉numfmt如何格式化输出数字。%.5f在本例中意味着将它们格式化为具有 5 位小数的浮点数。

  • --invalid=ignore

    该选项告诉numfmt当无法格式化数字时该怎么做。ignore在这种情况下,只需忽略有问​​题的输入并继续下一个输入。

默认情况下,numfmt应用IEEE 754 舍入规则- 如果您想要简单截断,可以添加--round=towards-zero。舍入选项的完整列表是updownfrom-zero(默认)、towards-zeronearest

您可以查看手册页以了解更多详细信息:


如果您想要 IEEE 754 舍入,但希望它严格应用于小数点后超过 5 位数字的浮点数,那么我建议使用perl- 它可以匹配正则表达式,例如sed,但允许您将sprintf表达式应用于捕获的模式:

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

与 GNU 类似sedperl可以通过添加选项来就地修改文件-i

答案2

您可以使用sed

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

添加-i选项以就地添加文件。

答案3

使用 GNU sed

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

输出:

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

使用扩展正则表达式-E

sed -E


.<five digits><n digits>用匹配图案。用\.([0-9]{5})[0-9]*捕获点后面的 5 位数字.([0-9]{5})

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

用点.和捕获的模式替换匹配项:

/.\1/

答案4

使用 GNU awk

awk '{print gensub(/([0-9]+\.[0-9]{5})[0-9]*/, "\\1", "g")}' input_file > output_file

它使用awk函数从给定文件 ( ) 中gensub选择一个十进制数 ( ) ,并将其拆分为两部分。第一部分有 5 位小数 ( ),第二部分是十进制数的其余部分 ( )。/([0-9]+\.[0-9]{5})[0-9]*/input_file([0-9]+\.[0-9]{5})[0-9]*

gensub然后用其第一部分 ( ) 替换选定的数字,"\\1"并对它可以找到的所有十进制数 ( "g")执行此操作input_file

然后,该命令将结果保存到输出文件(> output_file)。

相关内容