
Wenn ich also eine Variable habe
VAR='10 20 30 40 50 60 70 80 90 100'
und es wiederholen
echo "$VAR"
10 20 30 40 50 60 70 80 90 100
Weiter unten im Skript muss ich jedoch die Reihenfolge dieser Variable umkehren, damit sie etwa so angezeigt wird:
echo "$VAR" | <code to reverse it>
100 90 80 70 60 50 40 30 20 10
Ich habe es mit rev versucht und es hat buchstäblich alles umgekehrt, so dass das Ergebnis folgendermaßen war:
echo "$VAR" | rev
001 09 08 07 06 05 04 03 02 01
Antwort1
Auf GNU-Systemen ist das Gegenteil von cat tac:
$ tac -s" " <<< "$VAR " # Please note the added final space.
100 90 80 70 60 50 40 30 20 10
Antwort2
Für eine kurze Liste und in einer Variablen ist die Shell selbst die schnellste Lösung:
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
Ausgabe:
100 90 80 70 60 50 40 30 20 10
Hinweis: Die Aufteilungsoperation set -- $var
ist für die hier verwendete exakte Zeichenfolge sicher, jedoch nicht, wenn die Zeichenfolge Platzhalterzeichen ( *
, ?
oder []
) enthält. Sie kann set -f
bei Bedarf mit vor der Aufteilung vermieden werden. Derselbe Hinweis gilt auch für die folgenden Lösungen (sofern nicht anders angegeben).
Oder, wenn Sie mit der umgekehrten Liste eine andere Variable festlegen möchten:
var="10 20 30 40 50 60 70 80 90 100"
set -- $var
for i; do out="$i${out:+ }$out"; done
echo "$out"
Oder verwenden Sie nur die Positionsparameter.
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"
Oder verwenden Sie nur eine Variable (die var selbst sein kann):
Hinweis: Diese Lösung wird weder durch Globing noch durch IFS beeinflusst.
var="10 20 30 40 50 60 70 80 90 100"
a=" $var"
while [[ $a ]]; do
printf '<%s>' "${a##* }"
var="${a% *}"
done
Antwort3
awk
zur Rettung
$ 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
mit perl
, HöflichkeitWie liest man eine IP-Adresse rückwärts?geteilt von @steeldriver
$ echo "$var" | perl -lane '$,=" "; print reverse @F'
100 90 80 70 60 50 40 30 20 10
Oder mit bash
sich selbst durch Konvertieren des Strings in ein 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
Antwort4
zsh
:
print -r -- ${(Oa)=VAR}
$=VAR
teilt $VAR
auf $IFS
. (Oa)
sortiert die resultierende Liste in umgekehrter Array-Reihenfolge. print -r --
(wie in ksh
), dasselbe wie echo -E -
( zsh
spezifisch) isteine zuverlässige Version vonecho
: druckt seine Argumente unverändert, durch Leerzeichen getrennt und durch eine neue Zeile abgeschlossen.
Wenn Sie nur nach Leerzeichen teilen möchten und nicht nach allem, was $IFS
es enthält (standardmäßig Leerzeichen, Tabulator, Zeilenumbruch, NUL), weisen Sie entweder Leerzeichen zu $IFS
oder verwenden Sie eine explizite Teilung wie:
print -r -- ${(Oas: :)VAR}
So sortieren Sie in umgekehrter numerischer Reihenfolge:
$ 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
POSIX (würde also auch mit funktionieren bash
):
Nur mit in die Shell integrierten Mechanismen (außer printf
in einigen Shells) (besser für Variablen mit einem kurzen Wert):
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"
Mit awk
(besser für große Variablen, insbesondere mit bash
, aber bis zur Grenze der Größe der Argumente (oder eines einzelnen Arguments)):
awk '
BEGIN {
n = split(ARGV[1], a);
while (n) {printf "%s", sep a[n--]; sep = " "}
print ""
}' "$VAR"