ventajas - Tipos de versión de Unix
ventajas y desventajas de unix (7)
Tengo una lista de números de versión, digamos, por ejemplo, que están en un archivo versions.txt
1.2.100.4
1.2.3.4
10.1.2.3
9.1.2.3
Deseo ordenarlos para que estén ordenados por versión. es decir:
1.2.3.4
1.2.100.4
9.1.2.3
10.1.2.3
He intentado usar varios comandos de clasificación usando los parámetros "k", pero realmente no lo entiendo lo suficiente como para lograrlo. Cualquier ayuda sería apreciada.
BSD no proporciona -V
por defecto, por lo que la solución de Ben está lo más cerca posible. Para su comodidad, publico aquí nuestra versión que puede ordenar archivos como <label>-<version>.<ext>
:
% ls bla-*.ime | sed -Ee ''s/^(.*-)([0-9.]+)(/.ime)$//2.-1 /1/2/3/'' | sort -t. -n -k1,1 -k2,2 -k3,3 -k4,4 | cut -d/ -f2-
bla-1.ime
bla-1.0.ime
bla-1.0.0.ime
bla-1.1.ime
bla-1.1.29.ime
bla-1.2.3.ime
bla-1.2.29.ime
bla-1.2.30.ime
bla-1.3.ime
bla-1.3.0.ime
bla-1.3.1.ime
bla-1.3.10.ime
bla-1.3.20.ime
bla-1.7.ime
bla-1.11.29.ime
bla-2.3.2.ime
bla-11.2.2.ime
Breve explicación:
- Enumere los archivos que desea ordenar con
ls
. - Encuentre el número de versión y prefijo la línea con eso.
- Mientras lo hace, agregue
-1
al final para hacer primero un número de versión más corto (antes de.0
par). Puede cambiar-1
a0
si considera que1.3
es equivalente a1.3.0
. - Ordene las líneas usando la solución sugerida por Ben en el número de versión.
- Corte el prefijo de versión de la línea.
La lista ahora contiene una lista ordenada de versión de los nombres de archivo aplicables. Cualquier clasificación adicional en la parte de la label
se deja como un ejercicio para el lector.
En Perl:
sub compare_version_numbers {
my ($l,$r) = @_;
my @lx = split("//.",$l);
my @rx = split("//.",$r);
my $minlen = (@lx < @rx) ? @lx : @rx;
for (my $i=0; $i < $minlen; $i++) {
# make numeric by multiplying with 1
my $l_number = ($lx[$i] * 1);
my $r_number = ($rx[$i] * 1);
# compare with spaceship operator
my $l_vs_r = ($l_number <=> $r_number);
# return if decision is clear!
if ($l_vs_r != 0) {
return $l_vs_r
}
# otherwise, next part in array of version numbers
}
# if we are here, we could not decide - shortest entry wins!
return @lx <=> @rx
}
Este comando:
echo "1.2.100.4,1.2.3.4,10.1.2.3,9.1.2.3" | tr '','' ''/n'' | sort -V
Da salida:
1.2.3.4
1.2.100.4
9.1.2.3
10.1.2.3
La opción -V
es la más bonita, pero quería evitar instalar software nuevo / de otro tipo ya que mi género no tenía esa opción.
Este es el comando que funcionó para mí al final:
sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n test.txt
De los comentarios:
- Para invertir el orden:
sort -t. -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
sort -t. -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
- Para omitir el prefijo
v
:sort -t. -k 1.2,1n -k 2,2n -k 3,3n -k 4,4n
sort -t. -k 1.2,1n -k 2,2n -k 3,3n -k 4,4n
echo "1.2.100.4,1.2.3.4,10.1.2.3,9.1.2.3" | tr '','' ''/n'' | sort -k1,1n
Salida:
1.2.100.4
1.2.3.4
9.1.2.3
10.1.2.3
Deberías poder descifrar el resto. Buena suerte
sort -V versions.txt
Del man sort
:
-V
,--version-sort
tipo natural de números (versión) dentro del texto
Consulte también Detalles sobre el tipo de versión .
sort -n <versions.txt