Tengo un archivo de texto en este formato:
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Quiero ordenar este archivo por KEY
línea y mantener las siguientes 4 líneas con él en el resultado, por lo que el resultado ordenado debería ser:
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Hay alguna forma de hacer esto ?
Respuestas:
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 comando normal y utilizable para humanos. (Al menos, a los humanos que les gusta leer los manuales cuidadosamente y buscar ejemplos ...)AFAICT, no puede usar un patrón arbitrario para los registros, a menos que sus registros sean de tamaño fijo (en bytes, no en caracteres o líneas).
msort
tiene una-b
opción para registros que son bloques de líneas separadas por líneas en blanco.Puede transformar su entrada en un formato que funcione con
-b
bastante facilidad, poniendo una línea en blanco antes de cada###...
(excepto la primera).Por defecto, imprime estadísticas en stderr, por lo que al menos es fácil saber cuándo no se ordenó porque pensaba que toda la entrada era un solo registro.
msort
trabaja en tus datos. Elsed
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 dejé de lado las nuevas líneas adicionales.
No tuve suerte con
-r '#'
usar eso como separador de registros. Pensó que todo el archivo era un registro.fuente
msort
es muy útil; gracias (-r
parece que es porque hay más de un # que usé-d
y funcionómsort -qwr '#' ex
funciona para mí (bueno, cambia el separador de grabación de salida)Una solución es cambiar primero los avances de línea dentro de un bloque a un carácter no utilizado de su elección ('|' en el ejemplo a continuación), ordenar el resultado y volver a cambiar el separador elegido al avance de línea original:
fuente
;N
allí, y puede ser difícil encontrar un carácter que no se use en el texto mismo; es muy bueno parasort
oawk
... ser capaz de hacer una clasificación multilíneaperl -0
sorbe todo el archivo/(....)/g
unir y extraer los registrosprint sort ...
ordenarlos e imprimirlosfuente
Aquí hay otra forma que debería funcionar con cualquier número de líneas en una
KEY
sección:Esto funciona guardando el delimitador en una variable (para luego eliminarlo de la entrada). Luego agrega el
KEY*
a cada línea en su sección correspondiente usando un carácter ascii bajo (que es poco probable que ocurra en su entrada) como separador y luegon
numera todas las entradasl
usando el mismo separador. Entonces solo es cuestión desort
pasar por el tercer y primer campo ycut
marcar la columna central y luego restaurar los delimitadores a través de una finalsed
. Tenga en cuenta que con lo anterior,KEY12
se ordenará antes,KEY2
así que ajuste elsort
comando según sus necesidades.fuente
Puede usar la biblioteca POSIX Awk stdlib :
fuente