У меня есть текстовый файл в этом формате:
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Я хочу отсортировать этот файл KEY
построчно и сохранить в результате следующие 4 строки, поэтому отсортированный результат должен быть:
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Есть ли способ сделать это ?
Ответы:
msort(1)
был разработан, чтобы иметь возможность сортировать файлы с многострочными записями. Он имеет дополнительный графический интерфейс, а также нормальную и удобную для использования версию командной строки. (По крайней мере, люди, которые любят внимательно читать руководства и искать примеры ...)AFAICT, вы не можете использовать произвольный шаблон для записей, поэтому, если ваши записи имеют фиксированный размер (в байтах, а не символах или строках).
msort
действительно есть-b
опция для записей, которые являются блоками строк, разделенных пустыми строками.Вы можете преобразовать свой ввод в формат, который будет работать
-b
довольно легко, поставив пустую строку перед каждым###...
(кроме первого).По умолчанию он печатает статистику на stderr, поэтому, по крайней мере, легко определить, когда он не сортировался, потому что он думал, что весь ввод был одной записью.
msort
работает на ваших данных. Командаsed
добавляет новую#+
строку к каждой строке, кроме строки 1.,-w
сортирует всю запись (лексикографически). Есть варианты выбора того, какую часть записи использовать в качестве ключа, но они мне не нужны.Я также не учел лишние лишние строки.
Мне не повезло
-r '#'
использовать это как разделитель записей. Он думал, что весь файл был одной записью.источник
msort
очень полезно; спасибо (о,-r
кажется, это потому, что есть более одного # я использовал,-d
и это сработалоmsort -qwr '#' ex
работает для меня (ну, это изменяет разделитель записи rec.)Решение состоит в том, чтобы сначала изменить перевод строки внутри блока на неиспользуемый символ по вашему выбору ('|' в приведенном ниже примере), чтобы отсортировать результат и заменить выбранный разделитель на исходный перевод строки:
источник
;N
, и может быть трудно найти символ, который не используется в самом тексте; это очень хорошо дляsort
илиawk
... уметь выполнять многострочную сортировкуperl -0
хлебает весь файл/(....)/g
сопоставить и извлечь записиprint sort ...
сортировать и распечатывать ихисточник
Вот еще один способ работы с любым количеством строк в
KEY
разделе:Это работает путем сохранения разделителя в переменную (чтобы затем удалить его из ввода). Затем он добавляет
KEY*
к каждой строке в соответствующем разделе, используя низкий символ ascii (что вряд ли произойдет на вашем входе) в качестве разделителя, а затем убираетn
все значенияl
ines, используя один и тот же разделитель. В этом случае нужно толькоsort
указать 3-е и 1-е поле иcut
связать средний столбец, а затем восстановить разделители с помощью финалаsed
. Обратите внимание, что с учетом вышеизложенногоKEY12
будет сортировать, прежде чемKEY2
так настроитьsort
команду в соответствии с вашими потребностями.источник
Вы можете использовать библиотеку POSIX Awk stdlib :
источник