Сортировка научного номера с помощью Unix Sort

Я попытался отсортировать эти числа с помощью Unix, но он не работает:

    2e-13
    1e-91
    2e-13
    1e-104
    3e-19
    9e-99

Это моя команда:

sort -nr file.txt

Какой правильный способ сделать это?

Ответы

Ответ 1

Используйте -g (длинная форма --general-numeric-sort) вместо -n. Опция -g передает номера через strtod, чтобы получить их значение, и она распознает этот формат.

Я не уверен, что это доступно для всех реализаций sort, или только для GNU.

Ответ 2

если ваш sort не имеет -g, другим способом.

$ printf "%.200f\n" $(<file) |sort -n |xargs printf "%g\n"
1e-104
9e-99
1e-91
3e-19
2e-13
2e-13

$ sort -g file
1e-104
9e-99
1e-91
3e-19
2e-13
2e-13

$ printf "%.200f\n" `cat file` |sort -n |xargs printf "%g\n"

Ответ 3

Просто выполните две вещи:

  • Используйте -g (или --general-numeric-sort), чтобы sort правильно обрабатывать Exp-numbers.
  • Используйте LC_ALL=C. sort очень разумен для локали, если ваши данные могут содержать некоторые языковые символы, кроме ASCII. Таким образом, использование LC_ALL=C - универсальный подход для каждого случая, в котором вы используете sort, он делает sort для обработки входного потока двоичным, и у вас не было бы проблем.

Таким образом, универсальное решение:

cat file.txt | LC_ALL=C sort -gr | less

Также я сделал псевдоним для сортировки в моем файле .bashrc:

alias csort="LC_ALL=C sort"

для удобного использования.

Ответ 4

Хорошо, вот не полностью протестированная версия Python script. Предполагаемое использование:

sort_script.py file.txt

К сожалению, я разработал это в Windows, и с двумя разными версиями Python я не могу проверить его правильно. Предупреждение: требуется новый Python (с добавлением или изменением функций печати). Примечание: флаг back_to_file может быть необязательным параметром, хотя с Unix вы всегда можете перенаправить... даже в Windows вы можете.

#!/usr/bin/env python3.1
# Note: requires newer python

import sys

#Remove this line:
sys.argv = ('', 'file.txt')

assert(len(sys.argv) == 2)

with open(sys.argv[1], 'r') as fin:
    lines = fin.readlines()

lines_sorted = sorted(lines, key=lambda x: float(x))

back_to_file = False # Change this if needed

if back_to_file:
    with open(sys.argv[1], 'w') as fout:
        fout.writelines(lines_sorted)
else:
    for lns in lines_sorted:
        print(lns, end='') # Suppress new line