Сортировать пакеты строк по алфавиту

3

Примечание: дополнительный вопрос здесь: как отдельно отсортировать строки в нескольких «чанках», разделенных заголовками?


Так что я нашел ответ, как сортировать строки в текстовых файлах по алфавиту. Но это не совсем то, что мне нужно сделать. У меня есть этот файл с профилями, содержащими 15 различных параметров, который входит в инструмент на работе и считывается машиной для получения списка профилей.

К сожалению, форматирование этого файла выглядит так:

[ProfileB]
param1=z
param2=y
param3=x
[ProfileA]
param1=k
param2=l
param3=

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

[ProfileA]
param1=k
param2=l
param3=
[ProfileB]
param1=z
param2=y
param3=x

Я предполагаю, что есть, что работать с фиксированным количеством строк (имя + параметры) или с символом «[» в качестве идентификатора начала группы строк.

Но это не в моих силах в манипулировании текстом. В моем распоряжении консольная команда Sublime Text, R или Linux.

Пол Жиру
источник
«Инструмент» ли требует профилей , которые необходимо отсортировать?
Гленн Джекман
2
Я надеюсь, что кто-то может вам помочь, но тем временем вы должны выучить интерпретированный язык, не такой тяжелый, как C, и не такой беспокойный, как bash. Что-то вроде ruby ​​или python или perl.
Бароп
@glennjackman Нет, но если файл не отсортирован, профиль загружается в том же порядке, что и файл.
Пол Жиру
1
@ barlop У меня есть основы Python и Perl, и я хочу их использовать (именно это я и имел в виду под доступом к командной консоли)
Пол Жиру

Ответы:

3

Это работает в моем Debian:

sed '1 ! s/^\[/\x00\[/g' | sort -z | tr -d "\0"

Для работы с файлом (ами) используйте перенаправление (я), например { sed … ; } <input.txt >output.txt, где sed …находится вся команда.

Процедура выглядит следующим образом:

  1. sedвставляет нулевой символ перед каждым, [который находится в начале строки, если строка не является первой. Таким образом, нулевые символы разделяют профили.
  2. sort -z использует эти нулевые символы в качестве разделителей, поэтому сортирует целые профили, а не отдельные строки.
  3. tr удаляет нулевые символы
Камиль Мачоровски
источник
Нет претензий, я получил выходные файлы, когда я удалил filterдеталь, чтобы понять, что происходит. У меня их нет со всей командой.
Пол Жиру
1
Я думаю, что у меня есть проблема, и это возможно, потому что я не был достаточно ясен о том, что я хотел сделать. Ваше решение сортирует все строки внутри профиля (то, что я назвал param1, param2 и param3 в моем примере) в алфавитном порядке, но сохраняет первоначальный порядок профилей (если первый профиль в списке - [B], а второй - второй). [A], так и останется). Я хочу отсортировать имена профилей, а не содержащиеся в них параметры (которые уже расположены в алфавитном порядке.
Paul Giroud,
Мой плохой, извините, английский не мой родной язык, и я допустил ошибку в своем запросе! большое спасибо
Пол Жиру
0

Вот небольшой Perl-скрипт, который делает эту работу:

my %profiles;
my $profile;

while (<>) {
    if (/\[(.+)\]/) {
        $profile = $1;
        next;
    }
    next if !defined $profile;

    chop if /\n$/;
    push @{ $profiles{$profile} }, $_;
}

foreach my $key (sort keys %profiles) {
    print "[$key]\n";
    foreach my $line (sort @{ $profiles{$profile} }) {
        print "$line\n";
    }
}

Сохраните его, sortProfiles.plнапример, в файл и запустите:

perl sortProfiles.pl <inputFile.txt >outputFile.txt

Как это устроено

  1. Он читает входной файл ( while (<>)).
  2. Для каждого профиля [profile]во входном файле он запоминает свое имя в $profileпеременной.
  3. Он сохраняет каждую строку после заголовка профиля внутри массива.
  4. Затем он сортирует ключи %profilesхэша.
  5. Он также сортирует строки внутри массива.

В этом скрипте %profilesесть хеш. Его ключи - это имена профилей , а значения - массивы строк .
Таким образом, @{ $profiles{$profile} }массив, который хранит строки для имени профиля в $profileпеременной.

Алексей Иванов
источник
Я думаю, что это отвечает и на этот вопрос, и на дополнительный .
Алексей Иванов