Você pode alterar a ordem de classificação em zsh
globbing (consulte a resposta de Gilles ), mas ls
classificará seus argumentos de qualquer maneira e, por padrão, lexicograficamente.
Se o seu ls
é o GNU ls
, você pode usar a opção -v
para ordenar numericamente:
ls -1v
Ou:
ls -1vd -- *
Não é equivalente a sort -h
porque sort -h
é classificar coisas como a saída de du -h
, que é onde 1.12G
é maior que 999M
, enquanto ls -v
e zsh
s% Os qualificadores(n)
globbing são voltados para classificar coisas como números de versão (onde 1.20 é maior que 1.4 por exemplo).
Se você quiser um globbing que entenda esses bastos, você precisaria escrever uma função zsh sort para isso.
Com zsh, você pode definir a ordem de classificação glob com uma função e usá-la como *(o+that-function)
. that-function
pega o nome do arquivo para classificar na variável $REPLY
e deve retornar para a mesma variável, algo que zsh
pode ordenar lexicograficamente (ou numericamente se n
também for fornecido).
Algo como:
h() {
local -A x
local match
setopt localoptions extendedglob
x=(k 1 K 1 M 2 G 3 T 4 P 5 E 6)
REPLY=${REPLY//(#b)((|[0-9]#.)[0-9]##)([${(kj::)x}])/$((match[1]*2**$x[$match[3]]0))}
}
substituirá todos os 1.1G pelo seu valor (1181116006.4).
Que você pode usar como:
ls -1Ud -- *(no+h)
( -U
sendo a opção ls
do GNU para informar ls
não para ordenar seus argumentos).
Isso não funcionará bem, no entanto, com números com uma parte fracionária, pois classificaria 1.20
após 1.3
, por exemplo:
$ ls
1.20 1.3 3.1G 500M
$ ls -v1Ud -- *(no+h)
1.3
1.20
500M
3.1G
Para algo que classifica todos os tipos de números decimais flutuantes com sufixos opcionais (como -1e20M, 1E-20, 100k, 3000M), porque zsh
só pode classificar lexicograficamente ou numericamente limitado a inteiros decimais positivos, precisa de uma função para convertê-los em cadeias de caracteres que ordenem lexicograficamente na mesma ordem ou números inteiros decimais positivos que classifiquem numericamente na mesma ordem.
zsh
faz aritmética decimal e de ponto flutuante com números de 64 bits quando disponíveis, então poderíamos aplicar uma função de ponto flutuante que transforma esses números (ou pelo menos o intervalo suportado por zsh
floats) em um inteiro de 0 a 2 63 . Usar a função logaritmo pode ser uma opção. Algo como:
zmodload zsh/mathfunc
h() {
local -A x
local match v
setopt localoptions extendedglob
x=(k 1 K 1 M 2 G 3 T 4 P 5 E 6 Z 7 Y 8)
REPLY=${REPLY//(#b)([-+]|)(([0-9]#.|)[0-9]##([eE]([-+]|)[0-9]##|))\
([${(kj::)x}]|)/[$(([#10]1e15*(1500+ $match[1](745+log((v=$match[2]\
${${match[2]##*[Ee.]*}:+.}*2.**$x[$match[6]]0)==0?2.48e-324:v)))))]}
}
Para ser usado como:
print -rl -- *(no+h)
Ou, para retornar à classificação numérica para diferenciar 100000000000000001 e 100000000000000002 por exemplo (que possuem o mesmo logaritmo com zsh
float precision):
print -rl -- *(noe:h:on)
Em seguida, obtemos algo ainda melhor do que sort -h
:
$ ls | sort -h
-4
-3
+20
a2
b1
b10
b2
1e-20Y
1e3
1.20
1.3
3
20
999
1000 1e9
1000 900M
1001
1024
1k
12k
0.000000001G
$ print -rl -- *(noe:h:on)
-4
-3
0.000000001G
1.20
1.3
3
20
+20
999
1e3
1000 900M
1000 1e9
1001
1k
1024
1e-20Y
12k
a2
b1
b2
b10
Agora, para o seu problema específico do nyxmms2, para complementar a resposta de Gilles, eu sou um digitador preguiçoso, você também pode definir esse tempo como uma função seleção (em vez de "pedido") para música arquivos, como:
m() [[ $REPLY == (#i)*.(mp3|ogg)(-.) ]]
nyxmms2 *Zep*(n+m)
Ou use uma variável:
m='.(#i)(mp3|ogg)(n-.)'
nyxmms2 *Zep*$~m
Ou um alias global:
alias -g @m='./*.(#i)(mp3|ogg)(n-.)'
nyxmms2 @m
Para ativar o numericglobsort apenas para nyxmms2
, você pode:
preexec() {[[ $1 = nyxmms2* ]] && setopt numericglobsort}
precmd setopt nonumericglobsort