Eu tenho um arquivo de texto neste formato:
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Eu quero classificar este arquivo por KEY
linha e manter as próximas 4 linhas com ele no resultado para que o resultado classificado seja:
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
existe uma maneira de fazer isso?
Respostas:
msort(1)
foi projetado para poder classificar arquivos com registros de várias linhas. Ele possui uma interface gráfica opcional, além de uma versão normal e utilizável para humanos. (Pelo menos, seres humanos que gostam de ler os manuais com atenção e procurar exemplos ...)AFAICT, você não pode usar um padrão arbitrário para registros, portanto, a menos que seus registros tenham tamanho fixo (em bytes, não caracteres ou linhas).
msort
possui uma-b
opção para registros que são blocos de linhas separados por linhas em branco.Você pode transformar sua entrada em um formato que funcione com
-b
bastante facilidade, colocando uma linha em branco antes de cada###...
(exceto a primeira).Por padrão, ele imprime estatísticas no stderr, pelo menos é fácil saber quando não classificou, porque achou que toda a entrada era um único registro.
msort
funciona em seus dados. Osed
comando anexa uma nova linha a cada#+
linha, exceto a linha 1.-w
classifica o registro inteiro (lexicograficamente). Existem opções para escolher qual parte de um registro usar como chave, mas eu não precisava delas.Também deixei de fora as novas linhas extras.
Não tive sorte
-r '#'
em usar isso como separador de registros. Ele achava que o arquivo inteiro era um registro.fonte
msort
é muito útil; graças (cerca-r
parece que é porque há mais de um # eu usei-d
e funcionoumsort -qwr '#' ex
funciona para mim (bem chages o rec saída separador.)Uma solução é primeiro alterar os feeds de linha dentro de um bloco para um caractere não utilizado de sua escolha ('|' no exemplo abaixo), classificar o resultado e alterar novamente o separador escolhido para o feed de linha original:
fonte
;N
lá, e pode ser difícil encontrar um caractere que não seja usado no próprio texto; é muito bom para ,sort
ouawk
... ser capaz de fazer a triagem deperl -0
sorve o arquivo inteiro/(....)/g
combinar e extrair os registrosprint sort ...
classifique e imprima-osfonte
Aqui está outra maneira que deve funcionar com qualquer número de linhas em uma
KEY
seção:Isso funciona salvando o delimitador em uma variável (para removê-lo da entrada). Em seguida, anexa a
KEY*
cada linha em sua seção correspondente usando um caractere ASCII baixo (o que é improvável que ocorra em sua entrada) como um separador e depoisn
separa todas asl
colunas usando o mesmo separador. É apenas uma questão desort
entrar no terceiro e no primeiro campos ecut
colocar a coluna do meio e restaurar os delimitadores por meio de uma finalsed
. Observe que, com o exposto acima,KEY12
a classificação será feita antes;KEY2
portanto, ajuste osort
comando de acordo com suas necessidades.fonte
Você pode usar a biblioteca stdlib do POSIX Awk :
fonte