按字反轉量的內容

按字反轉量的內容

所以如果我有一個變量

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"

相關內容