#sorting #awk #unique #mediawiki
#сортировка #авк #уникальный #медиавики
Вопрос:
У меня есть этот текстовый файл, который мне нужно отсортировать по разделам.
#cat raw_file.txt
== other info ==
===instructions===
===english words===
this
is
only
test
=== missing words ===
==== include words ====
some
more
words
==== customer name ====
ram
sham
amar
akbar
anthony
==== cities ====
mumbai
delhi
pune
=== prefix ===
the
a
an
Если я сортирую его «как есть», то он начинается с 2 знаков равенства, за которыми следуют 3 знака равенства, а затем все слова. Как мне отсортировать слова по разделам отдельно?
# sort raw_file.txt
== other info ==
=== missing words ===
=== prefix ===
==== cities ====
==== customer name ====
==== include words ====
===english words===
===instructions===
a
akbar
amar
an
anthony
delhi
is
more
mumbai
only
pune
ram
sham
some
test
the
this
words
Это формат mediawiki, если это имеет значение. Я сортирую каждый раздел, и это занимает много времени.
#cat expected_output.txt
== other info ==
===instructions===
===english words===
is
only
test
this
=== missing words ===
==== include words ====
more
some
words
==== customer name ====
akbar
amar
anthony
ram
sham
==== cities ====
delhi
mumbai
pune
=== prefix ===
a
an
the
Комментарии:
1. может быть, добавить префикс к каждому разделу, затем выполнить обычную сортировку, а затем отрезать лишний префикс? Я думаю, что гораздо проще использовать что-либо на c / java / python / bash (текст канала для сортировки в подоболочке), чем только awk
Ответ №1:
при этом также будет сохранено точное количество пробелов, в обычном порядке сортировки они будут отображаться вверху, поэтому их нужно добавить в нижней части каждого раздела
$ awk 'BEGIN {s="sort"}
!NF {c }
/^=/ {close(s);
for(i=1;i<=c;i ) print "";
c=0;
print;
next}
NF {print | s}' file
будет генерироваться…
== other info ==
===instructions===
===english words===
is
only
test
this
=== missing words ===
==== include words ====
more
some
words
==== customer name ====
akbar
amar
anthony
ram
sham
==== cities ====
delhi
mumbai
pune
=== prefix ===
a
an
the
Ответ №2:
Если вы не беспокоитесь о сохранении пустых строк, вы можете использовать:
awk '/=/ {c } {print c 1, $0}' file.txt | sort -n | cut -d' ' -f2- | sed '/^$/d'
>== other info ==
>===instructions===
>===english words===
>is
>only
>test
>this
>=== missing words ===
>==== include words ====
>more
>some
>words
>==== customer name ====
>akbar
>amar
>anthony
>ram
>sham
>==== cities ====
>delhi
>mumbai
>pune
>=== prefix ===
>a
>an
>the
Этот подход работает путем добавления номера индекса к каждой строке и увеличения индекса на единицу каждый раз, когда строка содержит ‘=’, затем сортировка сначала по номеру индекса, затем по фактическому слову, затем удаление индекса и удаление пустых строк (которые заканчиваются вверху каждой ‘раздел’ после сортировки).
Редактировать
Я только что видел комментарий @Bing Wang — это в основном то, что он предложил вам сделать
Комментарии:
1. очень полезная идиома decorate-sort-undecorate , также известная как преобразование Шварца.
2. Просто чтобы отметить, что sort -u удалит дубликаты — поэтому используйте это вместо sort -n