Следующий конвейер должен выполнить работу
< your_input_file sort -t: -k1,1r | sort -t: -k1,1r | sed -E -n ':a;$p;N;s/([^:]*): *(.*)\n\1:/\1: \2 /;ta;P;D' | awk -F' ' '{ print $1, NF-1; print $0 }'
, где
sort
сортирует строки в соответствии с тем, что находится перед двоеточием, чтобы упростить последующую обработку - крипт c
sed
соединяет линии с общим поставщиком awk
считает позиции для поставщика и распечатывает все соответствующим образом.
Делая это с Только awk
, как предполагает KamilCuk в комментарии, будет намного более легкой работой; делать это с sed
было бы (для меня) кошмаром. Использование обоих, возможно, глупо, но я наслаждался этим.
Если вам нужно подробное объяснение, пожалуйста, прокомментируйте, и я найду время, чтобы предоставить его.
Вот сценарий
sed
записать одну команду на строку:
:a
$p
N
s/([^:]*): *(.*)\n\1:/\1: \2 /
ta
P
D
и вот как это работает:
:a
- это просто метка, с которой мы можем перепрыгнуть через t
est или b
команда ранчо; $p
- команда p
rint, применяемая только к адресу $
(последняя строка); обратите внимание, что все остальные команды применяются к каждой строке, так как адрес не указан; N
читает еще одну строку и добавляет ее в текущее пространство шаблона, помещая между собой \n
ewline; это создает мультилинию в пространстве образца s/([^:]*): *(.*)\n\1:/\1: \2 /
, фиксирующую то, что находится перед первым двоеточием в строке, ([^:]*)
, а также то, что следует за ним, (.*)
, избавление от доступных пробелов, *
; ta
t
оценивается, если предыдущая команда s
была успешной, и, если это так, передает управление в строку, помеченную a
(т. Е. go для шаг 1); P
печатает ведущую часть мультилинии вплоть до встроенной \n
ewline; D
удаляет ведущую часть мультилинии до и включая встроенный \n
ewline.