
Если у меня есть файл с содержимым, похожим на:
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