Bash - перевернуть массив

compgen -W "$ {all_commands}" - "$ {cur}" запускает compgen , передавая ему:

  • параметр -W с одним аргумент, значение переменной all_commands ;
  • один аргумент без параметра, значение переменной cur .

Аргумент - отмечает конец параметров. Даже если значение cur начинается с тире, оно не будет интерпретироваться как опция. Это чрезвычайно распространенное соглашение для синтаксического анализа параметров командной строки.

$ {COMPREPLY [@]: -} - странный вариант. Он использует конструкцию раскрытия параметров $ { ПЕРЕМЕННАЯ : - ТЕКСТ } , которая расширяется до значения ПЕРЕМЕННАЯ , если установлено и непустой и в ТЕКСТ иначе, в основном бессмысленным образом. Он принимает элементы массива COMPREPLY , за исключением того, что, если массив пуст или не определен, это приводит к пустой строке. Затем результат разбивается на слова, и каждое слово интерпретируется как шаблон глобуса . Это в точности эквивалентно $ {COMPREPLY [@]} , за исключением случаев, когда COMPREPLY не определено и действует set -u : в set - u , $ {COMPREPLY [@]} вызовет ошибку, если COMPREPLY не определен. Обратите внимание, в частности, что эта инструкция не добавляется к массиву COMPREPLY , а искажает его.Чтобы добавить в массив, правильный код будет

COMPREPLY+=($(compgen -W "${all_commands}" -- "${cur}") )

при условии, что вывод compgen содержит список шаблонов глобусов, разделенных пробелами.

16
25.12.2017, 03:55
5 ответов

Баш

array=(1 2 3 4 5 6 7)
echo "${array[@]} " | tac -s ' '

Или

array=(1 2 3 4 5 6 7)
reverse=$(echo "${array[@]} " | tac -s ' ')
echo ${reverse[@]}

Результат

7 6 5 4 3 2 1

Версия

$ tac --version
tac (GNU coreutils) 8.28
0
27.01.2020, 19:47

Для обращения произвольного массива (, который может содержать любое количество элементов с любыми значениями):

Сzsh:

array_reversed=("${(@Oa)array}")

В bash4.4+, учитывая, что bashпеременные не могут содержать байты NUL в любом случае, вы можете использовать GNU tac -s ''для элементов, напечатанных как записи с разделителями NUL:

readarray -td '' array_reversed < <(
  ((${#array[@]})) && printf '%s\0' "${array[@]}" | tac -s '')

Обратите внимание, однако, что массивы bash были вдохновлены массивами ksh, а не массивами csh/zsh, и больше похожи на ассоциативные массивы с ключами, ограниченными положительными целыми числами, (так называемые разреженные массивы ), и этот метод не не сохранять ключи массивов. Например, для любого массива типа:

array=( [3]=a [12]=b [42]=c )

Вы получаете

array_reversed=( [0]=c [1]=b [2]=a )

POSIXly, чтобы перевернуть единственный массив оболочки POSIX ($@, состоящий из $1, $2... )на месте:

code='set --'
n=$#
while [ "$n" -gt 0 ]; do
  code="$code \"\${$n}\""
  n=$((n - 1))
done
eval "$code"
3
27.01.2020, 19:47

Чистое решение bash будет работать как -лайнер.

$: for (( i=${#array[@]}-1; i>=0; i-- ))
>  do rev[${#rev[@]}]=${array[i]}
>  done
$: echo  "${rev[@]}"
7 6 5 4 3 2 1
2
27.01.2020, 19:47

вы также можете использоватьseq

array=(1 2 3 4 5 6 7)

for i in $(seq $((${#array[@]} - 1)) -1 0); do
    echo ${array[$i]}
done

в freebsd можно опустить -1 параметр приращения:

for i in $(seq $((${#array[@]} - 1)) 0); do
    echo ${array[$i]}
done
-1
27.01.2020, 19:47

Попробуйте это

#!/bin/bash

array=(1 2 3 4 5 6)
index=$((${#array[@]}-1))

for e in "${array[@]}"; do
  result[$((index--))]="$e"
done

echo "${result[@]}"

0
22.06.2021, 08:30

Теги

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