Tengo un archivo de campo de ancho fijo que estoy tratando de ordenar usando la utilidad de clasificación UNIX (Cygwin, en mi caso).
El problema es que hay un encabezado de dos líneas en la parte superior del archivo que se ordena al final del archivo (ya que cada línea de encabezado comienza con dos puntos).
¿Hay alguna manera de decirle a sort "pasar las dos primeras líneas sin clasificar" o especificar un orden que clasifique las líneas de dos puntos en la parte superior? Las líneas restantes siempre comienzan con un número de 6 dígitos (que en realidad es la clave I estoy clasificando) si eso ayuda.
Ejemplo:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
500123TSTMY_RADAR00
222334NOTALINEOUT01
477821USASHUTTLES21
325611LVEANOTHERS00
debería ordenar por:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
222334NOTALINEOUT01
325611LVEANOTHERS00
477821USASHUTTLES21
500123TSTMY_RADAR00
unix
sorting
command-line
Rob Gilliam
fuente
fuente
Respuestas:
Los paréntesis crean una subcapa, cerrando la salida estándar para que pueda canalizarla o redirigirla como si procediera de un solo comando.
fuente
tee >(head -n $header_size) | tail -n +$header_size | sort
, pero la cabeza parece correr detrás de latail|sort
tubería, por lo que el encabezado termina impreso al final. ¿Es esto determinista o una condición de carrera?cat
para redirigir el stdin a un archivo temporal, luego ejecute el comando anterior en ese nuevo archivo, pero está comenzando a ponerse lo suficientemente feo como para que probablemente sea mejor usar una de las soluciones basadas en awk que se dan en las otras respuestas.Si no le importa usar
awk
, puede aprovecharawk
las capacidades de tubería integradasp.ej.
Esto imprime las dos primeras líneas textualmente y pasa el resto
sort
.Tenga en cuenta que esto tiene la ventaja muy específica de poder clasificar selectivamente partes de una entrada canalizada. todos los otros métodos sugeridos solo ordenarán archivos planos que se pueden leer varias veces. Esto funciona en cualquier cosa.
fuente
$0
,print
es suficiente.Aquí hay una versión que funciona con datos canalizados:
Si su encabezado tiene varias líneas:
Esta solución es de aquí
fuente
extract_data | (read h; echo "$h"; sort)
, es lo suficientemente corto como para recordarlo. su ejemplo cubre más casos extremos. :) Esta es la mejor respuesta. trabaja en tuberias. no awk.extract_data | (read; sort)
En casos simples,
sed
puede hacer el trabajo con elegancia:o equivalente,
La clave está en
1q
: imprimir la primera línea (encabezado) y salir (dejando el resto de la entrada ensort
).Para el ejemplo dado, funcionará
2q
.El
-u
conmutador (sin búfer) es necesario para aquellos mensajes de correo electrónicosed
(en particular, GNU) que de otro modo leerían la entrada en fragmentos, consumiendo así los datos por los que desea pasarsort
.fuente
Puede usar
tail -n +3 <file> | sort ...
(tail generará el contenido del archivo desde la tercera línea).fuente
ejemplo:
fuente
Solo se necesitan 2 líneas de código ...
Para datos numéricos, se requiere -n. Para la ordenación alfa, la -n no es necesaria.
Archivo de ejemplo:
$ cat test.txt
Resultado:
$ cat a.tmp
fuente
Así que aquí hay una función bash donde los argumentos son exactamente como sort. Soporte de archivos y tuberías.
Cómo funciona. Esta línea comprueba si hay al menos un argumento y si el último argumento es un archivo.
Esto guarda el archivo en un argumento separado. Ya que estamos a punto de borrar el último argumento.
Aquí eliminamos el último argumento. Dado que no queremos pasarlo como un argumento de clasificación.
Finalmente, hacemos la parte awk, pasando los argumentos (menos el último argumento si era el archivo) para ordenar awk. Esto fue sugerido originalmente por Dave y modificado para tomar argumentos de clasificación. Confiamos en el hecho de que
$file
estará vacío si estamos canalizando, por lo tanto ignorado.Ejemplo de uso con un archivo separado por comas.
fuente
Con Python:
fuente
Aquí hay una función de shell bash derivada de las otras respuestas. Maneja tanto archivos como tuberías. El primer argumento es el nombre del archivo o '-' para stdin. Los argumentos restantes se pasan a ordenar. Un par de ejemplos:
La función de shell:
fuente
Esto es lo mismo que la respuesta de Ian Sherbin, pero mi implementación es: -
fuente
Esto hará lo que quieras.
fuente