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 ответа2

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 удаляет нулевые символы.
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 .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .