Bash - 反转数组

Bash - 反转数组

有没有简单的方法来反转数组?

#!/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

答案1

另一种非常规方法:

#!/bin/bash

array=(1 2 3 4 5 6 7)

f() { array=("${BASH_ARGV[@]}"); }

shopt -s extdebug
f "${array[@]}"
shopt -u extdebug

echo "${array[@]}"

输出:

7 6 5 4 3 2 1

如果extdebug启用,数组BASH_ARGV将按相反顺序包含函数中的所有位置参数。

答案2

非常规方法(都不是纯粹的bash):

  • 如果数组中的所有元素都只是一个字符(如问题中所示),您可以使用rev

     echo "${array[@]}" | rev
    
  • 否则,如果数组元素都不包含换行符:

     printf '%s\n' "${array[@]}" | tac | tr '\n' ' '; echo
    
  • 如果你可以使用zsh

     echo ${(Oa)array}
    

答案3

我已经回答了所写的问题,并且此代码反转了数组。 (以相反顺序打印元素而不反转数组只是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[@]}"

它适用于奇数和偶数长度的数组。

答案4

要交换数组位置(即使是稀疏数组)(自 bash 3.0 起):

#!/bin/bash
# Declare an sparse array to test:
array=([5]=101 [6]=202 [10]=303 [11]=404 [20]=505 [21]=606 [40]=707)
echo "Initial array values"
declare -p array

swaparray(){ local temp; temp="${array[$1]}"
             array[$1]="${array[$2]}"
             array[$2]="$temp"
           }

ind=("${!array[@]}")                         # non-sparse array of indexes.

min=-1; max="${#ind[@]}"                     # limits to one before real limits.
while [[ min++ -lt max-- ]]                  # move closer on each loop.
do
    swaparray "${ind[min]}" "${ind[max]}"    # Exchange first and last
done

echo "Final Array swapped in place"
declare -p array
echo "Final Array values"
echo "${array[@]}"

执行时:

./script
Initial array values
declare -a array=([5]="101" [6]="202" [10]="303" [11]="404" [20]="505" [21]="606" [40]="707")

Final Array swapped in place
declare -a array=([5]="707" [6]="606" [10]="505" [11]="404" [20]="303" [21]="202" [40]="101")

Final Array values
707 606 505 404 303 202 101

对于较旧的 bash,您需要使用循环(在 bash 中(自 2.04 起))并使用$a以避免尾随空格:

#!/bin/bash

array=(101 202 303 404 505 606 707)
last=${#array[@]}

a=""
for (( i=last-1 ; i>=0 ; i-- ));do
    printf '%s%s' "$a" "${array[i]}"
    a=" "
done
echo

对于 2.03 以后的 bash:

#!/bin/bash
array=(101 202 303 404 505 606 707)
last=${#array[@]}

a="";i=0
while [[ last -ge $((i+=1)) ]]; do 
    printf '%s%s' "$a" "${array[ last-i ]}"
    a=" "
done
echo

另外(使​​用按位求反运算符)(自 bash 4.2+ 起):

#!/bin/bash
array=(101 202 303 404 505 606 707)
last=${#array[@]}

a=""
for (( i=0 ; i<last ; i++ )); do 
    printf '%s%s' "$a" "${array[~i]}"
    a=" "
done
echo

相关内容