msort(1)
fue diseñado para poder ordenar archivos con registros de varias líneas. Tiene una interfaz gráfica de usuario opcional, así como una versión de línea de comandos normal y utilizable para humanos. (Al menos, humanos a los que les gusta leer los manuales detenidamente y buscar ejemplos...)
AFAICT, no puede usar un patrón arbitrario para los registros, a menos que sus registros tengan un tamaño fijo (en bytes, no en caracteres o líneas). msort
tiene un -b
opción para registros que son bloques de líneas separados por líneas en blanco.
Puede transformar su entrada en un formato que funcione con -b
muy fácilmente, poniendo una línea en blanco antes de cada ###...
(excepto el primero).
De forma predeterminada, imprime estadísticas en stderr, por lo que al menos es fácil saber cuándo no se clasificó porque pensó que toda la entrada era un solo registro.
msort
funciona con sus datos. El sed
el comando antepone una nueva línea a cada #+
línea excepto la línea 1. -w
ordena todo el registro (lexicográficamente). Hay opciones para elegir qué parte de un registro usar como clave, pero no las necesitaba.
También omití eliminar las nuevas líneas adicionales.
$ 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
No tuve suerte con -r '#'
para usarlo como separador de registros. Pensó que todo el archivo era un registro.
Una solución es cambiar primero los saltos de línea dentro de un bloque a un carácter no utilizado de su elección ('|' en el ejemplo a continuación), para ordenar el resultado y volver a cambiar el separador elegido al salto de línea original:
sed -e 'N; N; N; N; N; s/\n/|/g' file.txt \
| sort -k2,2 -t\| \
| sed 's/|/\n/g'
perl -0ne 'print sort /(#+[^#]*)/g' file.txt
perl -0
sorbe todo el archivo/(....)/g
hacer coincidir y extraer los registrosprint sort ...
clasificarlos e imprimirlos