Печатать файлы в обратном порядке из ассоциативного массива в bash

Не могли бы вы увидеть clion в ~/.local/share/applications? Если вы можете, вам нужно стереть папку или файл.

0
19.12.2016, 16:31
2 ответа

Чтобы напечатать список ключей, отсортированных в алфавитном порядке и предполагая сортировку GNU , вы можете сделать:

printf '%s\0' "${!hash[@]}" | sort -z | tr '\0' '\n'

Или перебрать отсортированный список ключей:

while IFS= read -rd '' -u3 key; do
  something with "${hash[$key]}"
done 3< <(printf '%s\0' "${!hash[@]}" | sort -z)

Если вы можете гарантировать, что ключи не будут содержать символов новой строки, вы можете упростить его до:

printf '%s\n' "${!hash[@]}" | sort

С zsh , это будет:

printf "%s\n" "${(ko@)hash}"

( k , чтобы получить ключи, o , чтобы упорядочить этот список, @ внутри двойных кавычек, чтобы сохранить пустой ключ, если таковой имеется (обратите внимание, что bash в настоящее время имеет ограничение в том, что у него не может быть хеш-элемента с пустым ключом)).

И чтобы перебрать их:

for key in "${(ko@)hash}"; do
  something with "$hash[$key]"
done

Обратите внимание, что за исключением последнего выше, мы предполагаем, что хэш содержит хотя бы один элемент (как printf '% s \ 0' без аргументов все равно будет выводить \ 0 , как если бы был элемент с пустым ключом).

В любом случае запись $ {! Current_file [@]} без кавычек не имеет смысла, поскольку это вызывает оператор split + glob для этого списка ключей.

2
28.01.2020, 02:26

Ассоциативный массив в bash похож на хэши / словари в типичных языках, и, как и они, он неупорядочен (фактически упорядочен в соответствии с внутренним значением хеш-функции). Таким образом, вы не можете ожидать, что вывод будет (обычно) отсортирован при итерации по (ассоциативным) ключам массива.

Вам нужно отсортировать его самостоятельно, например, отправив STDOUT в STDIN sort :

for key in ${!current_file[@]}; do
    echo $key      
done | sort 

или что-то подобное.


Если вы хотите сохранить порядок, чтобы вы могли выполнять любую операцию, основанную на порядке над ключами / значениями ассоциативного массива, вы можете сохранить другой индексированный массив в качестве ссылки для вставки. Следующее должно дать вам основную идею:

## Associative array `foo`
$ declare -A foo=([spam]=egg [baz]=cool)

## Reference indexed array `bar` containing the keys of `foo` sequentially indexed
$ bar=(spam baz)

## Retrieving in forward order
$ for i in "${bar[@]}"; do echo "$i :: ${foo[$i]}"; done
spam :: egg
baz :: cool

## Retrieving in reverse order
$ for ((i=${#bar[@]}-1; i>=0; i--)); do idx="${bar[$i]}"; echo "$idx :: ${foo[$idx]}"; done
baz :: cool
spam :: egg
1
28.01.2020, 02:26

Теги

Похожие вопросы