Сортировка массива на основе подстроки каждого элемента

Сортировка массива на основе подстроки каждого элемента

Как отсортировать массив на основе подстроки каждого элемента?
Например, задан массив типа

arr=( 2some05stuff 4more02stuff 3evenmore01stuff 1no04stuff )

Я хотел бы отсортировать элементы по числовому значению, которое им предшествует, stuffпоэтому в итоге я получу

3evenmore01stuff
4more02stuff
1no04stuff
2some05stuff

Я знаю, что параметр расширения флаги o/ Oпереупорядочивает массив, например

распечатать -rl "${(@on)arr}"
1no04stuff
2some05stuff
3evenmore01stuff
4more02stuff

и

распечатать -rl "${(@On)arr}"
4more02stuff
3evenmore01stuff
2some05stuff
1no04stuff

Я просто не знаю, возможно ли объединить эти флаги с функцией или другим расширением параметров, например, удалением индекса или расширением индекса...

решение1

Я не знаю способа сделать это в строке. С квалификаторами globs можно указать ключ сортировки ( *(oe\''REPLY=${${REPLY%stuff*}##*[^0-9]}'\')), но с модификаторами расширения параметров такого нет.

Что вы можете сделать, так это построить вспомогательный массив, содержащий ${sort_key}$'\0'${value}, т. е. добавить нулевой байт и исходное значение к ключу сортировки. Предполагая, что ключи сортировки не содержат нулевых байтов, сортировка этого массива дает желаемый порядок, а удаление префикса ключа сортировки дает желаемый результат.

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'}"

Связанный контент