Cómo simular “ordenar -V” en macOS

4 minutos de lectura

avatar de usuario de sphoid
esfoides

Escribí un script bash que necesito para trabajar de manera idéntica en Linux y macOS que se basa en el sort dominio. Estoy canalizando la salida de git tag -l a sort, para obtener una lista de todas las etiquetas de versión en el orden semántico correcto. ofertas GNU -V lo que hace que esto sea automático, pero macOS no admite este argumento, por lo que necesito descubrir cómo lograr este orden de clasificación sin él.

6.3.1.1
6.3.1.10
6.3.1.11
6.3.1.2
6.3.1.3
...

necesita ser clasificado como

6.3.1.1
6.3.1.2
6.3.1.3
...
6.3.1.10
6.3.1.11

  • Instalar clasificación GNU a través de homebrew brew install coreutils. brew info coreutils para más información.

    – ken

    28 de enero de 2014 a las 0:24

  • No estoy seguro de cuándo se agregó, pero al menos a partir de Mojave (macOS 10.14), sort hace apoyo -V.

    – cgrayson

    03/01/2019 a las 20:40

Puede utilizar funciones adicionales de git tag para obtener una lista de etiquetas que coincidan con un patrón y ordenadas correctamente para el orden de etiquetas de versión (normalmente sin ceros a la izquierda):

$ git tag --sort v:refname
v0.0.0
v0.0.1
v0.0.2
v0.0.3
v0.0.4
v0.0.5
v0.0.6
v0.0.7
v0.0.8
v0.0.9
v0.0.10
v0.0.11
v0.0.12

De $ man git-tag:

   --sort=<type>
       Sort in a specific order. Supported type is "refname
       (lexicographic order), "version:refname" or "v:refname" 
       (tag names are treated as versions). Prepend "-" to reverse 
       sort order. When this option is not given, the sort order
       defaults to the value configured for the tag.sort variable
       if it exists, or lexicographic order otherwise. See 
       git config(1).

  • Esta es una respuesta superior porque es independiente de la plataforma y no requiere el uso de sort en absoluto.

    – Fred Zimmermann

    3 de enero de 2018 a las 17:39


brew install coreutils

Si corutils está instalado, debería tener gsort en su Mac

gsort --version

  • si le falta la funcionalidad de mac cli, coreutils es imprescindible

    – durp

    8 de noviembre de 2018 a las 16:09

avatar de usuario de aax
hacha

Puede descargar coreUtils desde http://rudix.org/packages/index.html

Contiene gnusort con apoyo sort -V sintaxis

Avatar de usuario de John1024
Juan1024

sed 's/\b\([0-9]\)\b/0\1/g' versions.txt  | sort | sed 's/\b0\([0-9]\)/\1/g'

Para explicar por qué esto funciona, considere la primera sed manda por sí mismo. Con su entrada como versions.txt, la primera sed El comando agrega un cero inicial a los números de versión de un solo dígito, produciendo:

06.03.01.01
06.03.01.02
06.03.01.03
06.03.01.10
06.03.01.11

Lo anterior se puede ordenar normalmente. Después de eso, se trata de eliminar los caracteres agregados. En el mando completo, el último sed El comando elimina los ceros iniciales para producir el resultado final:

6.3.1.1
6.3.1.2
6.3.1.3
6.3.1.10
6.3.1.11

Funciona siempre que los números de versión sean 99 o menos. Si tiene números de versión superiores a 99 pero inferiores a 1000, el comando se vuelve un poco más complicado:

sed 's/\b\([0-9]\)\b/00\1/g ; s/\b\([0-9][0-9]\)\b/0\1/g' versions.txt  | sort | sed 's/\b0\+\([0-9]\)/\1/g'

Como no tengo una Mac, lo anterior se probó en Linux.

ACTUALIZACIÓN: en los comentarios, Jonathan Leffler dice que aunque el límite de palabras (\b) está en Mac regex docs, Mac sed no parece reconocerlo. Él sugiere reemplazar el primero sed con:

sed 's/^[0-9]\./0&/; s/\.\([0-9]\)$/.0\1/; s/\.\([0-9]\)\./.0\1./g; s/\.\([0-9]\)\./.0\1./g'

Entonces, el comando completo podría ser:

sed 's/^[0-9]\./0&/; s/\.\([0-9]\)$/.0\1/; s/\.\([0-9]\)\./.0\1./g; s/\.\([0-9]\)\./.0\1./g' versions.txt | sort | sed 's/^0// ; s/\.0/./g' 

Esto maneja números de versión hasta 99.

La ordenación estándar que viene instalada en OS X puede ordenar por campos usando un separador. Para que pueda ordenar los números de versión y cualquier sufijo.

Esto ordenará primero por sufijo y luego por las partes XYZ sort -s -t- -k 2,2n | sort -t. -s -k 1,1n -k 2,2n -k 3,3n -k 4,4nque también puede ordenar el número de versión en formato -Ng del git describe --tags dominio

0.11.1
0.11.4
0.11.9-1-ge6b0c59
0.12.0
0.12.1
0.12.2-1-g2d0a334
0.13.0
0.13.0-1-g7711b16
0.13.0-2-g32f91bd
0.13.0-3-g83e21c5
0.14.1-alpha
0.14.1
0.14.2

El -3-g83e21c5 anterior es un ejemplo de un sufijo que el git describe --tags El comando se agregará automáticamente a la última etiqueta para indicar la cantidad de confirmaciones desde la etiqueta (3) y el hash Git SHA de la confirmación más reciente (83e21c5)

Para invertir la ordenación en orden descendente, haga lo siguiente: sort -s -t- -k 2,2nr | sort -t. -s -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr

O puede definir una función de shell a su alrededor.

   version_sort() {
        # read stdin, sort by version number descending, and write stdout
        # assumes X.Y.Z version numbers

        # this will sort tags like pr-3001, pr-3002 to the END of the list
        # and tags like 2.1.4 BEFORE 2.1.4-gitsha

        sort -s -t- -k 2,2nr |  sort -t. -s -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
    }

o escríbalo en un pequeño archivo llamado version-sort, y colóquelo en algún directorio en su RUTA. Asegúrate de chmod +x en el archivo

#!/usr/bin/env bash
sort -s -t- -k 2,2nr |  sort -t. -s -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr

¿Ha sido útil esta solución?