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. O sed
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.
$ sed '2,$ s/^#\+/\n&/' unsorted.records | msort -b -w 2>/dev/null
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Não tive sorte -r '#'
em usar isso como separador de registros. Ele achava que o arquivo inteiro era um registro.