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

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

Если у меня есть файл с содержимым, похожим на:

FirstSection
    Unique first line in first section
    Unique second line in first section

SecondSection
    Unique first line in second section
    Unique second line in second section

...

NthSection
    Unique first line in Nth section
    Unique second line in Nth section

Можно ли использовать команды unix (например, sort, awk) для сортировки файла в алфавитном порядке по первой строке без отступа в каждой трехстрочной группе, сохраняя при этом строки с отступом в их существующей группе?

решение1

Используя Perl, вы можете запустить что-то вроде этого:

  • хлебать файл ( perl -0n)
  • разделить ввод по строкам без отступаsplit(/^(?=\S)/m)
  • сортировка и печать

perl -0ne 'print sort split(/^(?=\S)/m) ' ex 

решение2

Первый sed помещает каждый раздел на одну строку, используя текст <EOL>как разделитель между строками раздела. Затем я сортирую разделы и использую второй sed, чтобы вернуть каждый <EOL>обратно на новую строку.

sed -r ':r;$!{N;br};s:\n([[:blank:]])(\1*):<EOL>\1\2:g' file|sort|sed -r '/^$/d;:l;G;s:(.*)<EOL>(.*)(\n):\1\3\2:;tl;$s:\n$::'

Я не выбрал символ в качестве разделителя, так как он мог быть во входном файле, поэтому <EOL>вместо этого я использовал .

Выход:Я добавил новую строку после каждого раздела, кроме последнего, чтобы воссоздать стиль входного файла.

FirstSection
    Unique first line in first section
    Unique second line in first section

NthSection
    Unique first line in Nth section
    Unique second line in Nth section

SecondSection
    Unique first line in second section
    Unique second line in second section

решение3

с помощью GNU awkдля asort()и PROCINFO["sorted_in"]мы могли бы хранить каждую группу записей в связанном массиве awk на основе переноса строки между каждой группой; затем сортировать массив asort()и выводить все группы в цикле for.

awk '/^$/{ ++grpNr; next }
{ groups[grpNr]=(groups[grpNr]==""? "" : groups[grpNr] RS) $0 }
END{ asort(groups); 
     for(grp in groups) print groups[grp]
}'  infile

примечание: вы можете использовать PROCINFO["sorted_in"]элемент, чтобы задать нужный вам тип сортировки; например, PROCINFO["sorted_in"]="@val_str_desc"будет ли сортироватьсявалue нашего массива какулing и вубыв.заказ.


Или с помощью any awk(для создания блоков записей, разделенных символом Nul) + sort -z(для сортировки по символу Nul, а не по символу новой строки) + tr(для удаления ранее добавленного символа Nul с помощью awk):

<infile awk '/^$/{ ++grpNr; next }
{ groups[grpNr]=(groups[grpNr]==""? "\0" : groups[grpNr] RS) $0 }
END{ for(grp in groups) print groups[grp] }' |sort -z |tr -d '\0'

тестирование на входном файле, например:

BFirstSection
    Unique first line in first section
    Unique second line in first section

DSecondSection
    Unique first line in second section
    Unique second line in second section

Aanothersection...
    ...
    ...

CfourthSection
    Unique first line in Nth section
    Unique second line in Nth section

вы получите вывод как:

Aanothersection...
    ...
    ...
BFirstSection
    Unique first line in first section
    Unique second line in first section
CfourthSection
    Unique first line in Nth section
    Unique second line in Nth section
DSecondSection
    Unique first line in second section
    Unique second line in second section

Связанный контент