
Como classificar um array com base em uma substring de cada elemento?
por exemplo, dado um array como
arr=( 2some05stuff 4more02stuff 3evenmore01stuff 1no04stuff )
Eu gostaria de classificar os elementos pela sequência numérica que precede, stuff
para terminar com
3evenmore01stuff
4more02stuff
1no04stuff
2some05stuff
Eu sei que a expansão de parâmetros sinaliza o
/ O
reordena uma matriz, por exemplo
imprimir -rl "${(@on)arr}"
1no04stuff
2some05stuff
3evenmore01stuff
4more02stuff
e
imprimir -rl "${(@On)arr}"
4more02stuff
3evenmore01stuff
2some05stuff
1no04stuff
Só não sei se é possível combiná-los com uma função ou outra expansão de parâmetro, como, por exemplo, remoção de subscrito ou expansão de subscrito...
Responder1
Não conheço uma maneira de fazer isso inline. Com qualificadores globs, você pode especificar uma chave de classificação ( *(oe\''REPLY=${${REPLY%stuff*}##*[^0-9]}'\')
), mas isso não existe com modificadores de expansão de parâmetro.
O que você pode fazer é construir um array auxiliar contendo ${sort_key}$'\0'${value}
, ou seja, anexar um byte nulo e o valor original à chave de classificação. Supondo que as chaves de classificação não contenham bytes nulos, a classificação dessa matriz fornece a ordem desejada e a remoção do prefixo da chave de classificação fornece o resultado desejado.
typeset -a tmp; tmp=(); typeset -i i
for ((i=1; i<=$#arr; i++)); do tmp[$i]=${${arr[$i]%stuff*}##*[^0-9]}$'\0'$arr[$i]; done
print -lr "${(@)${(@o)tmp}#*$'\0'}"