2012-07-03 17 views
7

estoy tratando de ordenar una lista de nombres seguidos de otra cadena, tales como:¿Cómo ordenar con múltiples líneas en bash?

John Doe 
AVAIL 

Sara Doe 
CALL 

Jim Doe 
AVAIL 

que estoy tratando de resolver estos por su nombre, pero parece que no puede resolverlo con la especie. ¿Alguien puede proporcionar alguna orientación?

Mi resultado final sería el siguiente:

Jim Doe 
AVAIL 

John Doe 
AVAIL 

Sara Doe 
CALL 

muy apreciada!

+0

Curiosamente, de su ejemplo, no es claro si se ordena con respecto a la primera o la segunda línea;) Lo sentimos –

+0

De hecho, me gustaría ordenar por orden alfabético para la primera línea. –

Respuesta

6

Probablemente lejos de ser óptimo, pero

sed -r ':r;/(^|\n)$/!{$!{N;br}};s/\n/\v/g' names | sort | sed 's/\v/\n/g' 

parece hacer el trabajo (names es el fichero con los registros). Esto permite registros de longitud arbitraria, no solo 2 líneas.

+0

Definitivamente funcionó para mi propósito. –

+1

@lev para aquellos que no dominan "sed", ¿podrías dar una breve narración de la primera parte de la expresión? ¿Es su enfoque básico la eliminación de nuevas líneas (poniendo '\ v' en su lugar), ordenando una línea larga, y luego reemplazando' \ v' por '\ n'? – Levon

+0

@Levon Tienes razón :) Lee todo hasta una línea vacía (un registro), luego cambia las líneas nuevas a '\ v'. Ahora todos los registros están en líneas simples. Se ordenan, luego '\ v' se convierte de nuevo a' \ n'. –

0

No estoy seguro si le va a funcionar, pero con algunas limitaciones aquí hay una línea que hace lo que necesita.

awk '{if ((NR%2-1)==0) {line=sprintf("%-30s",$0)} else {print line ":" $0}}' | \ 
    sort --key=1,30 | tr ':' '\n' 

Supuestos: No hay líneas en blanco entre registros, el nombre es siempre inferior a 30 caracteres y no hay : utilizado en el texto.

Estoy seguro de que puede averiguar cómo cambiarlo si las suposiciones son diferentes.

En pocas palabras, combina dos líneas usando ':' como separador, rellena la primera línea a 30 caracteres y ordena con los primeros 30 caracteres. Luego rompe líneas.

0

no directamente, pero puede usar alguna forma intermedia como esta. supongo que su valor (LLAMADA, AVISO, etc.) es limitado. de lo contrario, debe usar patrones que son más complicados, pero se puede hacer. En realidad nada se puede hacer en bash :-)

cat sorting | sed -n '1h; 1!H; ${ g; s/\nCALL\n/::CALL::/g; s/\nAVAIL\n/::AVAIL::/g ; s/\nAVAIL/::AVAIL::/g p }' | sort | sed "s/::/\n/g" 
Jim Doe 
AVAIL 

John Doe 
AVAIL 

Sara Doe 
CALL 
Cuestiones relacionadas