Есть ли простой способ обратить массив?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
так что я бы получил: 7 6 5 4 3 2 1
вместо:1 2 3 4 5 6 7
Есть ли простой способ обратить массив?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
так что я бы получил: 7 6 5 4 3 2 1
вместо:1 2 3 4 5 6 7
Я ответил на вопрос как написано, и этот код переворачивает массив. (Печать элементов в обратном порядке без обращения к массиву - это просто for
цикл с обратным отсчетом от последнего элемента до нуля.) Это стандартный алгоритм «поменять местами первый и последний».
array=(1 2 3 4 5 6 7)
min=0
max=$(( ${#array[@]} -1 ))
while [[ min -lt max ]]
do
# Swap current first and last elements
x="${array[$min]}"
array[$min]="${array[$max]}"
array[$max]="$x"
# Move closer
(( min++, max-- ))
done
echo "${array[@]}"
Это работает для массивов нечетной и четной длины.
Еще один нетрадиционный подход:
Выход:
Если
extdebug
включено, массивBASH_ARGV
содержит в функции все позиционные параметры в обратном порядке.источник
Нетрадиционный подход (все не чисто
bash
):если все элементы в массиве только один символ (как в вопросе), вы можете использовать
rev
:в противном случае:
и если вы можете использовать
zsh
:источник
tac
, как противоположностьcat
довольно хорошо помню, СПАСИБО!rev
, я должен отметить, чтоrev
это не будет работать правильно для чисел с двумя цифрами. Например, элемент массива с12
использованием rev будет напечатан как21
. Попробуй ;-)Если вы действительно хотите обратное в другом массиве:
Потом:
дает:
Это должно правильно обрабатывать случаи, когда индекс массива отсутствует, скажем, у вас был
array=([1]=1 [2]=2 [4]=4)
, и в этом случае цикл от 0 до самого высокого индекса может добавить дополнительные, пустые элементы.источник
shellcheck
выводит два предупреждения:array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
и для:echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
declare
строка.declare -n
похоже, не работает в версиях Bash до 4.3.Чтобы поменять местами позиции массива (даже с разреженными массивами) (начиная с bash 3.0):
По исполнению:
Для более старого bash вам нужно использовать цикл (в bash (начиная с 2.04)) и использовать,
$a
чтобы избежать пробела:Для Баш с 2.03:
Также (используя оператор побитового отрицания) (начиная с bash 4.2+):
источник
Гадкий, не поддерживаемый, но однострочный
источник
eval eval echo "'\"\${array[-'{1..${#array[@]}}']}\"'"
.ind=("${!array[@]}");eval eval echo "'\"\${array[ind[-'{1..${#array[@]}}']]}\"'"
Хотя я не собираюсь рассказывать что-то новое, и я также буду использовать
tac
для реверса массива, хотя стоит упомянуть приведенное ниже однострочное решение с использованием bash версии 4.4:Тестирование:
Помните, что имя переменной внутри read - это имя исходного массива, поэтому для временного хранения вспомогательный массив не требуется.
Альтернативная реализация путем корректировки IFS:
PS: я думаю, что вышеприведенные решения не будут работать в
bash
нижеприведенной версии4.4
из-за различнойread
реализации встроенной функции bash.источник
IFS
Версия работает , но это также печать:declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Используя Bash4.4-5
. Вы должны удалить;declare -p array
в конце первой строки, тогда это работает ...declare -p
- это просто быстрый способ заставить bash печатать реальный массив (индекс и содержимое). Вам не нужна этаdeclare -p
команда в вашем реальном сценарии. Если что-то пойдет не так в ваших назначениях массивов, вы можете оказаться в случае, когда${array[0]}="1 2 3 4 5 6 10 11 12"
= все значения хранятся в одном индексе - используя echo, вы не увидите никакой разницы. Для быстрой распечатки массиваdeclare -p array
вы получите реальные значения массива и соответствующее значение в каждом индексе.read -d'\n'
метод у вас не сработал?read -d'\n'
работает отлично.Чтобы обратить произвольный массив (который может содержать любое количество элементов с любыми значениями):
С
zsh
:В
bash
4.4+, учитывая, чтоbash
переменные в любом случае не могут содержать байты NUL, вы можете использовать GNUtac -s ''
для элементов, напечатанных как записи с разделителями NUL:POSIXly, чтобы перевернуть массив оболочки POSIX (
$@
, из$1
,$2
...):источник
Чистое решение Bash, будет работать как один вкладыш.
источник
rev+=( "${array[i]}" )
кажется проще.Вы также можете рассмотреть возможность использования
seq
в freebsd вы можете опустить параметр приращения -1:
источник
удар
Или
Результат
7 6 5 4 3 2 1
Версия
источник
tac
уже упоминалось: unix.stackexchange.com/a/412874/260978 , unix.stackexchange.com/a/467924/260978 , unix.stackexchange.com/a/413176/260978