Eu tenho uma lista de linhas semelhante ao índice de um livro, digamos
day
satur-
sun-
holy-
night
ball
to-
eve
election
christmas
Agora quero classificar essas linhas da maneira óbvia: quero agrupar cada entrada “pai” ( day
, night
, eve
) com suas respectivas entradas “filhas” recuadas ( satur-
, sun-
, …) e classificar esses grupos por sua entrada pai. Também quero classificar as entradas secundárias em qualquer grupo.
Assim, a saída desejada é:
day
holy-
satur-
sun-
eve
christmas
election
night
ball
to-
Qual a melhor forma de conseguir isso usando ferramentas básicas do Unix como sort
?
Responder1
Você pode escolher um caractere que provavelmente não ocorrerá em seu arquivo de texto, acrescentar o nome do pai + esse caractere a cada linha filho, classificar e remover o nome do pai e o separador de cada linha filho, por exemplo, com gnu
sed e um caractere ascii baixo como\x02
sed '/^[^[:blank:]]/h;//!G;s/\(.*\)\n\(.*\)/\2\x02\1/' infile | sort | sed 's/.*\x02//'
Como funciona:
o primeiro sed
faz o seguinte:
/^[^[:blank:]]/h
- copia linhas não recuadas (pais) sobre o espaço de espera
//!G
- nas linhas recuadas (filhos) anexa o conteúdo do espaço de espera ao espaço padrão
s/\(.*\)\n\(.*\)/\2\x02\1/
- troca as linhas no espaço padrão substituindo o \n
ewline por \x02
depois disso, sort
e remova tudo até e inclusive \x02
com um 2ºsed 's/.*\x02//'