Как отсортировать строки текстового файла в порядке ASCII?

Вопрос или проблема

Предположим, у меня есть следующий файл.txt:

foo-a baz
foo bar
foo-c baz

Если я выполню sort file.txt, я получу такой же вывод:

foo-a baz
foo bar
foo-c baz

Поскольку (пробел) идет перед - в ASCII, я ожидал увидеть следующий вывод:

foo bar
foo-a baz
foo-c baz

Даже если sort рассматривает целые слова, я все равно ожидал, что foo будет перед foo-a и foo-c.

Я пробовал sort -d (словарный), sort -g (общий числовой) и sort -h (человеческий числовой) без успеха. Есть ли способ получить нужный мне порядок с помощью sort? В противном случае с использованием другого базового инструмента (я понимаю, что это было бы легко сделать на python, perl, ruby и т.д., но я пишу оболочку, которая должна быть переносимой).

В локали C сортировка предполагает основание на порядке символов в ASCII, даже на (редких) системах, которые не основаны на ASCII.

На практике 99,99% систем основаны на ASCII, и реализации sort в этой локали просто сортируют по байтовому значению, не заботясь о том, какие символы эти байты представляют.

Аспект сортировки локализации контролируется переменной окружения LC_COLLATE, хотя будьте осторожны, что LC_ALL, если установлено, имеет приоритет над всеми остальными переменными LC_*.

LC_CTYPE также контролирует, как байты декодируются в символы на входе (и символы кодируются обратно в байты на выходе), установка его на C также помогает избежать возможной двусмысленности, если в входных данных есть не-ASCII символы, и делает декодирование/кодирование быстрее (просто пропуск, как упоминалось выше).

И как только вы установите LC_CTYPE на C, вы можете также установить LC_MESSAGES и все остальные, так как, вероятно, сообщения об ошибках на языке пользователя в любом случае не могут быть отображены в ASCII.

Так что в целом, установка LC_ALL на C решает все проблемы:

$ LC_ALL=C sort file.txt
foo bar
foo-a baz
foo-c baz

Больше об этом по адресу: Что делает “LC_ALL=C”?

Ответ или решение

Чтобы отсортировать строки текста в файле в порядке ASCII, вы можете использовать утилиту sort в Unix-подобных операционных системах. Однако, как показано в вашем примере, поведение sort может зависеть от настройки локали системы. Давайте рассмотрим, как можно достичь желаемого результата сортировки с учетом специфики ASCII.

Шаги для сортировки строк по порядку ASCII

  1. Создание файла: Убедитесь, что у вас есть текстовый файл, содержащий строки, которые вы хотите отсортировать. Например, создайте файл file.txt с содержимым:

    foo-a baz
    foo bar
    foo-c baz
  2. Проверка локали: По умолчанию sort может использовать локаль, отличную от C, что может привести к неожиданным результатам сортировки. Ваша задача — использовать локаль C, которая гарантирует, что символы сортируются в соответствии с их числовыми значениями в ASCII.

  3. Установка локали: Перед выполнением команды сортировки установите переменную окружения LC_ALL в C. Это можно сделать прямо в командной строке:

    LC_ALL=C sort file.txt

    Эта команда означает, что sort будет работать в стандартной локали, где порядок символов строго соответствует их значениям в таблице ASCII.

  4. Ожидаемый результат: После выполнения вышеуказанной команды вы должны получить следующий вывод:

    foo bar
    foo-a baz
    foo-c baz

Дополнительные параметры и их использование

  • LC_COLLATE: Эта переменная окружения определяет правила сортировки. Установив LC_COLLATE=C, вы обеспечите сортировку в соответствии с ASCII. Однако использование LC_ALL=C более эффективно, так как оно переопределяет все переменные локали, касающиеся каталога.

  • LC_CTYPE: Эта переменная управляет кодировкой символов. На большинстве систем использование C также помогает избежать проблем с не-ASCII символами, так как это позволит избежать любой неопределенности при трактовке байтов.

Завершение

Использование команды sort в сочетании с правильной установкой локали позволит вам достичь ожидаемого порядка строк в текстовом файле. Это решение является универсальным и совместимо с различными Unix-подобными системами, что делает его отличным выбором для написания переносимых скриптов.

Если же вы хотите более сложную сортировку или фильтрацию, вы можете рассмотреть использование языков скриптов, таких как Python или Perl, но для стандартных задач с текстом sort с корректно заданной локалью будет вполне достаточно.

Таким образом, для сортировки строк в вашем файле по порядку ASCII, достаточно выполнить следующую команду:

LC_ALL=C sort file.txt

Этот метод является простым и эффективным способом достижения нужного результата.

Оцените материал
Добавить комментарий

Капча загружается...