Reversing a variable's contents by words
On GNU systems, the reverse of cat is tac:
$ tac -s" " <<< "$VAR " # Please note the added final space.
100 90 80 70 60 50 40 30 20 10
For a short list, and in a variable, the shell itself is the fastest solution:
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
Output:
100 90 80 70 60 50 40 30 20 10
Note: the split operation in set -- $var
is safe for the exact string used here, but will not be so if the string contains wildcard characters (*
, ?
or []
). It may be avoided with set -f
before the split, if needed.
The same note is also valid for the following solutions (except where noted).
Or, if you want to set some other variable with the reverse list:
var="10 20 30 40 50 60 70 80 90 100"
set -- $var
for i; do out="$i${out:+ }$out"; done
echo "$out"
Or using only the positional parameters.
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"
Or using only one variable (which may be var itself):
Note: This solution is not affected by globing nor IFS.
var="10 20 30 40 50 60 70 80 90 100"
a=" $var"
while [[ $a ]]; do
printf '<%s>' "${a##* }"
var="${a% *}"
done
awk
to the rescue
$ 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
with perl
, courtesy How to read an IP address backwards? shared by @steeldriver
$ echo "$var" | perl -lane '$,=" "; print reverse @F'
100 90 80 70 60 50 40 30 20 10
Or, with bash
itself by converting the string to array
$ 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