Сортировка текстовых файлов с несколькими строками в виде строки

Как говорит @Tombart, задержка связана с ожиданием таймаута разрешения IPv6.

Другой возможный вариант действий - дать приоритет IPv4 в /etc/gai.conf

Из комментариев в /etc/gai.conf

# Для сайтов, предпочитающих IPv4-соединения, измените последнюю строку на.
#
precedence ::ffff:0:0/96 100

После изменения gai.conf, вам нужно перезапустить любое приложение, использующее библиотеку DNS resolver, чтобы изменения вступили в силу.

Имейте в виду, что если вы используете BIND-сервер без возможности подключения IPv6, я советую отключить IPv6 в named и брать из корневых подсказок IPv6-адреса. Очевидно, что он все равно будет пытаться разрешать адреса AAAA.

Итак, для конфигурации BIND,

В /etc/default/bind9 добавьте -4 для IPv4 адресов:

OPTIONS="-4 -u bind"

и в /etc/bind/db.root удалите все строки с AAAA DNS корнями.

13
31.12.2016, 17:45
5 ответов

msort (1) был разработан для сортировки файлов с многострочными записями.У него есть необязательный графический интерфейс, а также обычная версия командной строки, удобная для использования людьми. (По крайней мере, люди, которые любят внимательно читать руководства и искать примеры ...)

AFAICT, вы не можете использовать произвольный шаблон для записей, поэтому, если ваши записи не имеют фиксированного размера (в байтах, а не в символах или линий). msort имеет параметр -b для записей, которые представляют собой блоки строк, разделенных пустыми строками.

Вы можете легко преобразовать свой ввод в формат, который будет работать с -b , поставив пустую строку перед каждым ### ... (кроме первого ).

По умолчанию он выводит статистику на stderr, поэтому, по крайней мере, легко определить, когда он не сортируется, потому что он считал, что весь ввод был единственной записью.


msort работает с вашими данными. Команда sed добавляет новую строку к каждой строке # + , кроме строки 1. -w сортирует всю запись (лексикографически). Есть варианты выбора, какую часть записи использовать в качестве ключа, но они мне не понадобились.

Я также не стал убирать лишние символы новой строки.

$ sed '2,$ s/^#\+/\n&/' unsorted.records | msort -b -w 2>/dev/null 
####################################
KEY1
VAL11
VAL12
VAL13
VAL14

####################################
KEY2
VAL21
VAL22
VAL23
VAL24

####################################
KEY3
VAL31
VAL32
VAL33
VAL34

Мне не повезло с -r '#' , чтобы использовать это в качестве разделителя записей. Он думал, что весь файл был одной записью.

13
27.01.2020, 19:52

Вот еще один способ, который должен работать с любым количеством строк в секции KEY :

# extract delimiter
delim=$(head -n1 <infile)
sed '/#/d;/KEY/h;G;s/\n/\x02/' infile | nl -ba -nrz -s $'\002' | sort -t $'\002' -k3 -k1,1 |
cut -d $'\002' -f2 | sed '/KEY/{x;s/.*/'"${delim}"'/;G}'

Это работает путем сохранения разделителя в переменной (чтобы затем удалить его из ввода). Затем он добавляет KEY * к каждой строке в соответствующем разделе, используя символ с низким ascii (который вряд ли встречается в вашем вводе) в качестве разделителя, а затем n объединяет все l ines с использованием того же разделителя. Тогда остается только сортировка по 3-му и 1-му полю и вырезание среднего столбца, а затем восстановление разделителей с помощью финального sed . Обратите внимание, что в приведенном выше примере KEY12 будет отсортировать перед KEY2 , поэтому настройте команду sort в соответствии с вашими потребностями.

2
27.01.2020, 19:52

Вы можете использовать библиотеку POSIX Awk stdlib :

#!/usr/local/bin/awklib -f
$0 ~ "#" {x++}
{q[x] = q[x] ? q[x] RS $0 : $0}
END {
  arr_sort(q)
  for (x in q) print q[x]
}
2
27.01.2020, 19:52
perl -0ne 'print sort /(#+[^#]*)/g' file.txt
  • perl -0 смазывая весь файл
  • /(....) /g сопоставить и извлечь записи
  • печать сортировки ... отсортировать и распечатать их
5
27.01.2020, 19:52

Решение состоит в том, чтобы сначала изменить перевод строки внутри блока на неиспользуемый символ по вашему выбору ('|' в примере ниже), чтобы отсортировать результат и вернуть выбранный разделитель на исходный перевод строки:

sed -e 'N; N; N; N; N; s/\n/|/g' file.txt \
| sort -k2,2 -t\| \
| sed 's/|/\n/g'
9
27.01.2020, 19:52

Теги

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