ordenando números de versão
December 30, 2008
Quando eu quero listar versões em ordem, a ordenação de strings padrão, seja pelo
comando sort
ou pelo sort padrão de qualquer linguagem de progamação, não serve.
terceiro@morere:~/src/noosfero (master)$ git tag
0.1.0
0.10.0
0.10.1
0.10.2
0.10.3
0.11.0
0.11.1
0.11.2
0.11.3
0.11.4
0.11.5
0.12.0
0.2.0
0.3.1
0.4.0
0.5.0
0.6.0
0.7.0
0.8.0
0.9.0
terceiro@morere:~/src/noosfero (master)$ git tag | sort
0.1.0
0.10.0
0.10.1
0.10.2
0.10.3
0.11.0
0.11.1
0.11.2
0.11.3
0.11.4
0.11.5
0.12.0
0.2.0
0.3.1
0.4.0
0.5.0
0.6.0
0.7.0
0.8.0
0.9.0
O script a seguir resolve meu caso:
#!/usr/bin/ruby
out = $stdin.readlines.map { |s| s.strip }.sort do |v1,v2|
(v1 == v2) ? 0 : (system("dpkg --compare-versions #{v1} le #{v2}") ? -1 : 1)
end
puts out
Salvei ele em ~/bin/version-sort
e fix um chmod +x ~/bin/version-sort
.
Aí eu consigo fazer coisas assim:
terceiro@morere:~/src/noosfero (master)$ git tag | version-sort
0.1.0
0.2.0
0.3.1
0.4.0
0.5.0
0.6.0
0.7.0
0.8.0
0.9.0
0.10.0
0.10.1
0.10.2
0.10.3
0.11.0
0.11.1
0.11.2
0.11.3
0.11.4
0.11.5
0.12.0
UPDATE: Pedro me indicou por e-mail uma alternativa usando opções do próprio sort
:
terceiro@morere:~/src/noosfero (master)$ git tag | sort -n -t . -k 1,1 -k 2,2 -k 3,3
0.1.0
0.2.0
0.3.1
0.4.0
0.5.0
0.6.0
0.7.0
0.8.0
0.9.0
0.10.0
0.10.1
0.10.2
0.10.3
0.11.0
0.11.1
0.11.2
0.11.3
0.11.4
0.11.5
0.12.0
De fato pra esse caso específico funciona que é uma beleza, e é simples fazer uma alias do shell com o comando todo. Mesmo assim essa abordagem usando o dpkg --compare-version
tem a vantagem de ser genérica: eu posso abstrair o formato do número de versão que o dpkg se vira: x.y.z, x.y, x.y.z.w, x:y.z, etc.