Разрезание чисел в определенные десятичные дроби

Я хочу сократить все числа в файле только до пятого знака после запятой. Например, у меня есть этот файл:

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 десятичными разрядами.

6
задан 28 August 2019 в 22:50

4 ответа

Если Вы не возражаете против целых чисел, также преобразовываемых в плавающую точку, Вы могли бы использовать 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. Полный список округления опций up, down, from-zero (значение по умолчанию), towards-zero, nearest.

Можно просмотреть страницу справочника для получения дополнительной информации:


Если Вы хотите округление IEEE 754, но хотите, чтобы оно применялось строго к числам с плавающей точкой больше чем с 5 цифрами после точки, то я предложил бы использовать perl - это может соответствовать регулярным выражениям, как sed, но позволяет Вам применять a sprintf выражение к полученному шаблону:

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

Как GNU sed, perl может изменить файл, оперативный путем добавления -i опция.

5
ответ дан 23 November 2019 в 07:16

Можно использовать sed:

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

Добавить -i опция добавить файл на месте.

6
ответ дан 23 November 2019 в 07:16

С GNU awk:

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

Это использует awk функция gensub выбрать десятичное число (/([0-9]+\.[0-9]{5})[0-9]*/) из данного файла (input_file) и разделение это в две части. Первая часть имеет 5 десятичных разрядов (([0-9]+\.[0-9]{5})) и вторая часть является остальной частью десятичного числа ([0-9]*).

gensub затем заменяет выбранное число его первой частью ("\\1") и делает это для всех десятичных чисел, которые это может найти ("g") в input_file.

Команда затем сохраняет результат к выходному файлу (> output_file).

4
ответ дан 23 November 2019 в 07:16

С 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/

5
ответ дан 23 November 2019 в 07:16

Другие вопросы по тегам:

Похожие вопросы: