Saltar la navegación

sort

El comando sort ordena y muestra por la salida estándar las líneas de los ficheros especificados o de la entrada estándar en ausencia de estos.

La ordenación por defecto es alfabética por líneas completas, pero también es posible realizar la ordenación numéricamente. En la ordenación alfabética si un carácter no es un espacio, letra o dígito, esa posición no se tendrá en cuenta para todas las líneas a ordenar.

La sintaxis general de sort es:

sort [opción...] [fichero...]

Cuando sort lleva varios ficheros, lo primero que hace es concatenarlos y después ordena el resultado de la concatenación. Es posible unir a estos ficheros la entrada estándar, para lo cual debemos añadir el signo - entre ellos:

$ cat f1.txt
hola
cama
ocaso
jota
$ cat f2.txt
zapato
amapola
persiana
$ sort f1.txt - f2.txt > orden.txt
camorra
alcoba
$ cat orden.txt
alcoba
amapola
cama
camorra
hola
jota
ocaso
persiana
zapato

o también:

$ who | sort lista_antigua - > lista_nueva

Si queremos que la salida vaya a un fichero, podemos usar redireccionamiento, como en los dos ejemplos anteriores, pero podemos usar también la opción -o. Esta opción es obligatoria si el fichero de salida tiene que ser el mismo que uno de los de entrada, pues usando redireccionamiento esto no se puede hacer.

$ sort f1.txt f2.txt -o f1.txt
$ cat f1.txt
amapola
cama
hola
jota
ocaso
persiana
zapato

Para que la ordenación sea por líneas completas, como hasta ahora, pero usando el criterio numérico, usaremos la opción -n:

$ cat f3.txt
100     gambones
2       guisantes
10      gambones
5       gambones
$ sort f3.txt
100     gambones
10      gambones
2       guisantes
5       gambones
$ sort -n f3.txt
2       guisantes
5       gambones
10      gambones
100     gambones

Si la ordenación es por líneas completas y numérica, pero algunas líneas no comienzan por un número, la ordenación será alfabética en primer lugar para esas líneas y numérica en segundo lugar para las demás.

$ cat f4.txt 
10   texto1
1    texto2
zapato
5    texto3
alameda
4    texto4
$ sort -n f4.txt
alameda
zapato
1    texto2
4    texto4
5    texto3
10   texto1

Otras opciones útiles son:

-f   No se tendrá en cuenta la diferencia entre mayúsculas y minúsculas.
-g Es como -n, para una ordenación numérica, pero es capaz de tratar también números reales, con punto decimal o en notación científica (info sort).
-r Aplica el orden inverso.
-u Solo muestra una línea por cada grupo de líneas repetidas.
-b Descarta para la ordenación los comienzos de las líneas formados por espacios y tabuladores.
-M   
Aplica el orden de los meses del año. Esto se utiliza cuando ordenamos por fechas donde los meses del año van en letras.
-h Ordena numéricamente número con unidades como 2K, 1G, etc.
-R Realiza una ordenación aleatoria, lo que se traduciría en un barajado de las líneas del fichero.
-V Hace una ordenación en base a números de versión.
$ cat f4.txt 
1
2
3
4
5
6
7
8
9
10
$ sort -R f4.txt
3
5
4
6
9
2
10
7
8
1
$ sort -R f4.txt
9
6
1
10
2
8
4
5
3
7
$ cat f4.txt 
3.2
1.02
1.1
3.18
2.01
$ sort -V f4.txt
1.1
1.02
2.01
3.2
3.18

Hasta ahora el campo de comparación ha sido la línea entera, pero este puede reducirse a un trozo de la línea, e incluso pueden especificarse varios campos de comparación dentro de la línea, es decir, ordenar en función del valor de dos o más trozos de la línea.

La forma de dividir una línea en varios campos o trozos, es a través de la opción -t que especifica el carácter delimitador de los campos. Veamos algunos ejemplos:

  • El guión como carácter divisor de campos: -t - ó -t '-'
  • El espacio como carácter divisor de campos: -t ' '
  • El ampersand como carácter divisor de campos: -t & ó -t '&'

Por defecto, el campo separador es la cadena vacía que hay entre un carácter no blanco y un carácter blanco (espacio, tabulador). Así la cadena '   uno      dos'  tendría dos campos por defecto, el primero sería '  uno' y el segundo sería '      dos'.

Con la opción -k se especifica el trozo de línea que se utilizará para ordenar y podemos repetir la opción cuantas veces queramos. La forma general de la opción -k es la siguiente:

-k pos1[,pos2]

que viene a definir el trozo de línea que va desde la posición pos1 hasta la posición pos2 (ambas incluidas) y si pos2 no se pone, entonces hasta el final de la línea. Tanto pos1 como pos2, tienen la siguiente sintaxis:

f[.c][opts]

donde f es el número de un campo y c el número del primer carácter que se va a usar de ese campo. Tanto f como c comienzan a numerarse por el número 1. Un 0 para c en pos2 indicaría hasta el final del campo. Si .c no se pone en pos1 se asume el 1 y si no se pone en pos2 se asume el 0, es decir, se asume el comienzo del campo y el final del campo, respectivamente. Por último, opts se refiere a opciones de ordenación:

  • n para orden numérico.
  • b para eliminar los espacios por la izquierda.
  • M para ordenar por los nombres de los meses.
  • r para aplicar el orden inverso.
  • g para ordenar números reales.
  • f para no tener en cuenta la diferencia entre mayúsculas y minúsculas.

Por ejemplo, para ordenar los usuarios conectados al sistema por el nombre de la terminal a la que están conectados:

$ who
usuario  tty7         2013-09-04 12:42 (:0)
usuario  pts/0        2013-09-05 19:43 (:0)
$ who | sort -k 2b,2
usuario  pts/0        2013-09-05 19:43 (:0)
usuario  tty7         2013-09-04 12:42 (:0)

Para ordenar los últimos 5 últimos procesos en ejecución por su PID en orden inverso:

$ ps -A | tail -5 | sort -nbr -k 1,1
 9191 pts/0    00:00:00 sort
 9190 pts/0    00:00:00 tail
 9189 pts/0    00:00:00 ps
 9179 ?        00:00:00 kworker/0:2
 9112 ?        00:00:00 kworker/0:0

Un comando sort como el siguiente:

$ sort -t : -k 2,2n -k 5.3,5.4 datos.txt

primeramente crearía los campos basándose en el carácter dos puntos. Posteriormente, ordenaría en primer lugar de forma numérica por el campo número 2, y los empates los ordenaría alfabéticamente por el trozo del campo número 5 que va desde el carácter 3 hasta el carácter 4.

En el ejemplo siguiente:

$ ls -l
total 48
drwxr-xr-x 12 usuario usuario 4096 may 12 19:55 Descargas
drwxr-xr-x  3 usuario usuario 4096 may 12 22:20 Documentos
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Escritorio
-rw-r--r--  1 root    root      52 may 19 20:41 f4.txt
drwxr-xr-x  2 usuario usuario 4096 may 18 21:45 Imágenes
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Música
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Plantillas
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Público
-rw-r--r--  1 usuario usuario 1386 may 19 12:22 salida
drwxr-xr-x  2 usuario usuario 4096 may 15 08:20 tmp
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Vídeos
drwx------  5 usuario usuario 4096 abr 17 21:47 VirtualBox VMs
$ ls -l | tail -n +2 | sort -k 1.5,1.7 -k 8.4b,8.5n
drwx------  5 usuario usuario 4096 abr 17 21:47 VirtualBox VMs
-rw-r--r--  1 usuario usuario 1386 may 19 12:22 salida
-rw-r--r--  1 root    root      52 may 19 20:41 f4.txt
drwxr-xr-x  2 usuario usuario 4096 may 15 08:20 tmp
drwxr-xr-x  3 usuario usuario 4096 may 12 22:20 Documentos
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Escritorio
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Música
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Plantillas
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Público
drwxr-xr-x  2 usuario usuario 4096 abr  5 20:44 Vídeos
drwxr-xr-x  2 usuario usuario 4096 may 18 21:45 Imágenes
drwxr-xr-x 12 usuario usuario 4096 may 12 19:55 Descargas

se muestra el listado del comando ls ordenado en primer lugar alfabéticamente por los tres permisos del grupo y en segundo lugar numéricamente por los minutos. El filtro tail que va en la tubería lo que hace es eliminar la línea de total de bloques que muestra ls en los listados largos.

Licencia: licencia de software libre GPL