У меня есть список строк, похожий на индекс книги, скажем
day
satur-
sun-
holy-
night
ball
to-
eve
election
christmas
Теперь я хочу отсортировать эти строки очевидным образом: я хочу сгруппировать каждую «родительскую» запись ( day
, night
, eve
) с соответствующими им отступами «дочерних» записей ( satur-
, sun-
, …) и отсортировать эти группы по их родительской записи. Я также хочу отсортировать дочерние записи внутри любой заданной группы.
Таким образом, желаемый результат:
day
holy-
satur-
sun-
eve
christmas
election
night
ball
to-
Как мне лучше всего этого добиться, используя основные инструменты Unix, такие как sort
?
решение1
Вы можете выбрать символ, который вряд ли встретится в текстовом файле, добавить родительское имя + этот символ к каждой дочерней строке, отсортировать, а затем удалить родительское имя и разделитель из каждой дочерней строки, например, с помощью gnu
sed и символа с низким кодом ASCII, например:\x02
sed '/^[^[:blank:]]/h;//!G;s/\(.*\)\n\(.*\)/\2\x02\1/' infile | sort | sed 's/.*\x02//'
Как это работает:
1-й элемент sed
выполняет следующие действия:
/^[^[:blank:]]/h
- копирует строки без отступа (родительские) в пространство удержания;
//!G
- в строках с отступом (дочерних) добавляет содержимое пространства удержания в пространство шаблона;
s/\(.*\)\n\(.*\)/\2\x02\1/
- меняет местами строки в пространстве шаблона , заменяя \n
строку ewline на строку \x02
после нее, sort
и удаляет все до и включая \x02
строку 2-го элемента.sed 's/.*\x02//'