所以如果我有一个变量
VAR='10 20 30 40 50 60 70 80 90 100'
并回显出来
echo "$VAR"
10 20 30 40 50 60 70 80 90 100
但是,在脚本的更下方,我需要反转该变量的顺序,以便它显示为类似的内容
echo "$VAR" | <code to reverse it>
100 90 80 70 60 50 40 30 20 10
我尝试使用 rev,它实际上扭转了一切,所以结果是
echo "$VAR" | rev
001 09 08 07 06 05 04 03 02 01
答案1
在 GNU 系统上, cat 的逆序是 tac:
$ tac -s" " <<< "$VAR " # Please note the added final space.
100 90 80 70 60 50 40 30 20 10
答案2
对于简短的列表和变量,shell 本身是最快的解决方案:
var="10 20 30 40 50 60 70 80 90 100"
set -- $var; unset a
for ((i=$#;i>0;i--)); do
printf '%s%s' "${a:+ }" "${!i}"
a=1
done
echo
输出:
100 90 80 70 60 50 40 30 20 10
注意: 中的分割操作set -- $var
对于此处使用的确切字符串是安全的,但如果字符串包含通配符(*
、?
或[]
),则情况就不那么安全了。set -f
如果需要的话,可以在拆分之前避免它。相同的注释也适用于以下解决方案(除非另有说明)。
或者,如果您想使用反向列表设置其他变量:
var="10 20 30 40 50 60 70 80 90 100"
set -- $var
for i; do out="$i${out:+ }$out"; done
echo "$out"
或者仅使用位置参数。
var="10 20 30 40 50 60 70 80 90 100"
set -- $var
a=''
for i
do set -- "$i${a:+ $@}"
a=1
done
echo "$1"
或者仅使用一个变量(可能是 var 本身):
注意:此解决方案不受 globing 或 IFS 的影响。
var="10 20 30 40 50 60 70 80 90 100"
a=" $var"
while [[ $a ]]; do
printf '<%s>' "${a##* }"
var="${a% *}"
done
答案3
awk
来救援
$ var='10 20 30 40 50 60 70 80 90 100'
$ echo "$var" | awk '{for(i=NF; i>0; i--) printf i==1 ? $i"\n" : $i" "}'
100 90 80 70 60 50 40 30 20 10
与perl
, 礼貌如何反向读取IP地址?由 @steeldriver 共享
$ echo "$var" | perl -lane '$,=" "; print reverse @F'
100 90 80 70 60 50 40 30 20 10
或者,bash
通过将字符串转换为数组来使用自身
$ arr=($var)
$ for ((i=${#arr[@]}-1; i>=0; i--)); do printf "${arr[i]} "; done; echo
100 90 80 70 60 50 40 30 20 10
答案4
zsh
:
print -r -- ${(Oa)=VAR}
$=VAR
分裂$VAR
于$IFS
.(Oa)
以相反的数组顺序对结果列表进行排序。print -r --
(如),与(具体)ksh
相同是echo -E -
zsh
的可靠版本echo
:按原样打印其参数,以空格分隔,以换行符终止。
如果您只想在空格上分割,而不是在任何$IFS
包含的内容上分割(默认情况下为空格、制表符、换行符、nul),请将空格分配给$IFS
,或使用显式分割,例如:
print -r -- ${(Oas: :)VAR}
要按相反的数字顺序排序:
$ VAR='50 10 20 90 100 30 60 40 70 80'
$ print -r -- ${(nOn)=VAR}
100 90 80 70 60 50 40 30 20 10
POSIXly(因此也可以与 一起使用bash
):
仅使用 shell 内置机制(某些 shell 除外printf
)(对于具有短值的变量更好):
unset -v IFS # restore IFS to its default value of spc, tab, nl
set -o noglob # disable glob
set -- $VAR # use the split+glob operator to assign the words to $1, $2...
reversed_VAR= sep=
for i do
reversed_VAR=$i$sep$reversed_VAR
sep=' '
done
printf '%s\n' "$reversed_VAR"
With awk
(对于大变量更好,尤其是 with bash
,但不超过参数(或单个参数)大小的限制):
awk '
BEGIN {
n = split(ARGV[1], a);
while (n) {printf "%s", sep a[n--]; sep = " "}
print ""
}' "$VAR"