如何在bash onliner FOR循环中反转数组?

我怎样才能扭转我为一个定义的数组执行循环的顺序

要遍历数组,我正在这样做:

$ export MYARRAY=("one" "two" "three" "four") $ for i in ${MYARRAY[@]}; do echo $i;done one two three four 

有一个函数,我可以颠倒数组的顺序?

一个想法是生成一个倒序索引序列,并通过使用这个倒序索引来调用元素,但也许有一个更快的select,或者至less更容易阅读。

你可以使用C风格的循环:

 for (( idx=${#MYARRAY[@]}-1 ; idx>=0 ; idx-- )) ; do echo "${MYARRAY[idx]}" done 

对于具有“孔”的数组,元素${#arr[@]}的数目不对应于最后一个元素的索引。 您可以创build另一个索引数组,并以相同的方式向后走:

 #! /bin/bash arr[2]=a arr[7]=b echo ${#arr[@]} # only 2!! indices=( ${!arr[@]} ) for ((i=${#indices[@]} - 1; i >= 0; i--)) ; do echo "${arr[indices[i]]}" done 

你可以使用tac ,这意味着它可以反转线条。

 MYARRAY=("one" "two" "three" "four") for item in "$MYARRAY"; do echo "$item"; done | tac # four # three # two # one 
 _arr+=( '"${_arrev} is an actual "${array[@]}"' ) ⏎ _arr+=( '"${_arrev} is created as a result"' ) _arr+=( '"of reversing the key order in"' ) _arr+=( '"this "${_arr}. It handles zsh and"' ) _arr+=( '"bash arrays intelligently by tracking"' ) _arr+=( '"shell "$ENV." quotes=fine ( i hope ) "' ) . <<REVERSE /dev/stdin ⏎ _arrev=( $(: $((l=${#_arr[@]}${ZSH_VERSION++1})) ; printf '"${_arr[$(('$l'-%d))]}" ' `seq 1 $l`) ) REVERSE echo ; printf %s\\n ${_arrev} "shell "$ENV." quotes=fine ( i hope ) " "bash arrays intelligently by tracking" "this "${_arr}. It handles zsh and" "of reversing the key order in" "${_arrev} is created as a result" "${_arrev} is an actual "${array[@]}" 

这应该处理任何可能的arrays,我想。

如果你对这里发生的事情感兴趣,我build议你先看看这里 。 那么也许在这里 ,肯定在这里 ,如果你有时间, 在这里和这里 。

在所有这些答案中,我将讨论这里的文档(以及其他许多方面) ,您可以使用这些文档来获得优势。 例如,我讨论了两次 – 评估variables,这是上面做的,在一个声明一个函数,全局声明在另一个函数名为"_$1"在5或6行 – 其中大部分是_$1() { func body ; } _$1() { func body ; } 如果你正确使用它是非常方便的。

关于bash/zsh,之间的自动切换bash/zsh,那么这是另一回事,但也很简单。 看到这里 。

这个怎么样:

 for i in `printf '%s\n' "${MYARRAY[@]}"|tac`; do echo $i; done 

输出是:

 four three two one 

限制:如果数组包含换行符,则不起作用。 作为一种解决方法,您可以实现以下function:

 reverse(){ reversed=();local i;for ((i=$#;i>0;i--)); do reversed+=("${!i}");done; } 

并以这种方式使用它:

 reverse "${MYARRAY[@]}" && for i in "${reversed[@]}"; do echo $i; done 

如果你正在谈论一个连续的数值数组(比如说删除bash历史logging),那么你可以按照相反的顺序列出这个数组,例如:

 for i in {16..10}; do history -d $i; done 

我意识到这是一个脱离主题,我为此道歉,但我认为这可能是值得一提的。

简单的string:

 % unset c; a="1 2 3 4 5"; for b in $a; do c="$b $c"; done; echo $c 

5 4 3 2 1

你确定你想要数组语法??:

  % unset c; declare -ac; a=(1 2 3 4 5); i=0; for b in ${a[*]}; \ do c[$((${#a[@]}-$i))]=$b; i=$(($i+1)); done; echo ${c[*]} 

5 4 3 2 1