bash
Eu não acho que o bash
tenha suporte interno para isso ainda. As opções seriam implementar manualmente um algoritmo de classificação ou invocar sort
para fazer a classificação.
Se considerarmos que os elementos da matriz podem conter qualquer valor de byte, mas 0 em bash
, para fazer isso de forma confiável, precisaríamos passar a lista de elementos delimitados por NUL e usar a opção -z
para sort
(fora do padrão, mas disponível no tipo GNU ou no tipo FreeBSD).
O
bash-4.4 (lançado em setembro de 2016) facilita a introdução de uma opção -d
em seu readarray
builtin para especificar o delimitador.
Para classificar a matriz a
na matriz b
:
readarray -td '' b < <(printf '%ssortarray() for array do
readarray -tf '' "$array" < <(
eval "printf '%sb=()
while IFS= read -rd '' item; do b+=("$item"); done < <(
printf '%ssortarray() for array do eval '
tmp=()
while IFS= read -rd "" item; do tmp+=("$item"); done < <(
printf "%s$ a=('' 12 2 d é f $'a\nb')
$ printf '<%s>\n' "${(@o)a}"
<>
<12>
<2>
<a
b>
<d>
<é>
<f>
$ printf '<%s>\n' "${(@no)a}"
<>
<2>
<12>
<a
b>
<d>
<é>
<f>
" "${'"$array"'[@]}" | sort -z)
'"$array"'=("${tmp[@]}")'
done
' "${a[@]}" | sort -z)
' \"\${$array[@]}\" | sort -z")
done
' "${a[@]}" | sort -z)
classificaria o array de forma confiável. Use as opções -n
, -r
para sort
para classificar numericamente ou em ordem inversa (ou qualquer critério de classificação suportado por sort
).
Para implementar sua função sortarray
(classifica todos os arrays passados por nome como argumentos):
b=("${(@o)a}")
Com versões anteriores de bash
, você pode usar read -d
em um loop para obter o mesmo:
sortarray() for array do eval "$array=(\"\${(@o)$array}\")"; done
Para a função sortarray
:
set -s -- "${a[@]}"
b=("$@")
zsh
O Zsh tem suporte embutido para classificar matrizes.
você pode usar o sinalizador de expansão do parâmetro o
para classificar lexicalmente ( O
para ordem inversa). Você pode adicionar o sinalizador n
para ordenar numericamente:
sortarray() for array do
eval 'set -s -- "${'"$array"'[@]}"; '"$array"'=("$@")'
done
Em localidades que ainda não classificam caso de forma independente, você também pode adicionar o sinalizador i
para isso.
Para atribuir a uma matriz:
readarray -td '' b < <(printf '%ssortarray() for array do
readarray -tf '' "$array" < <(
eval "printf '%sb=()
while IFS= read -rd '' item; do b+=("$item"); done < <(
printf '%ssortarray() for array do eval '
tmp=()
while IFS= read -rd "" item; do tmp+=("$item"); done < <(
printf "%s$ a=('' 12 2 d é f $'a\nb')
$ printf '<%s>\n' "${(@o)a}"
<>
<12>
<2>
<a
b>
<d>
<é>
<f>
$ printf '<%s>\n' "${(@no)a}"
<>
<2>
<12>
<a
b>
<d>
<é>
<f>
" "${'"$array"'[@]}" | sort -z)
'"$array"'=("${tmp[@]}")'
done
' "${a[@]}" | sort -z)
' \"\${$array[@]}\" | sort -z")
done
' "${a[@]}" | sort -z)
Portanto, uma função sortarray
seria como:
b=("${(@o)a}")
AT & T ksh (ksh88 ou ksh93, ambos podem ser encontrados em alguns sistemas)
sortarray() for array do eval "$array=(\"\${(@o)$array}\")"; done
set -s
ordena a lista de argumentos e os armazena nos parâmetros posicionais. A ordem é lexical.
Uma função sortarray
poderia ser:
set -s -- "${a[@]}"
b=("$@")