In der Zeichenfolge "12345" wird die Zeichenfolge "54321" ausgegeben. Am besten ohne Tools und Regex von Drittanbietern.
Antworten:
Einfach:
var="12345"
copy=${var}
len=${#copy}
for((i=$len-1;i>=0;i--)); do rev="$rev${copy:$i:1}"; done
echo "var: $var, rev: $rev"
Ausgabe:
$ bash rev
var: 12345, rev: 54321
ascii hexBytes umzukehren .
Ich weiß, dass Sie "ohne Tools von Drittanbietern" gesagt haben, aber manchmal ist ein Tool einfach zu offensichtlich das richtige und es ist standardmäßig auf den meisten Linux-Systemen installiert:
[madhatta@risby tmp]$ echo 12345|rev
54321
rev <<< 12345in Bash, Zsh und Ksh. (Nicht Dash noch Csh.)
echo '\xff' |rev. Ich habe nie gesagt, dass echo -edas funktionieren würde, deshalb scheint es ein bisschen hart zu sein, mich über die Kohlen zu harken, wenn es nicht so ist.
revwirkt in jeder Zeile unabhängig und scheint keine Befehlszeilenoptionen zu haben, die dies ändern. Wie das Beispiel von @ Equidamoid zeigt (was übrigens nichts damit zu tun hat echo -e), wird außerdem davon ausgegangen , dass es sich bei der Zeichenfolge um eine ordnungsgemäß codierte Zeichenfolge handelt . Wenn Sie etwas um Bytes umkehren müssen (z. B. wenn Sie nicht mit Binärdaten anstelle von tatsächlichem Text arbeiten), funktioniert diese Lösung nicht. [Hinweis: Um die Formatierung zu korrigieren, habe ich diesen Kommentar gelöscht und erneut veröffentlicht. Entschuldigung für mögliche Phantombenachrichtigungen.]
rev | tail -r(BSD) oder rev | tac(GNU) kehren auch Linien um:
$ rev <<< $'12\n34' | tail -r
43
21
$ rev <<< $'12\n34' | gtac
43
21
Wenn LC_CTYPE C ist, kehrt rev die Bytes der Multibyte-Zeichen um:
$ LC_CTYPE=C rev <<< あの
��め�
$ export LC_ALL=C; LC_ALL=en_US.UTF-8 rev <<< あの
のあ
tac. Beachten Sie, dass tacdie Übergabe eines anderen Trennzeichens als die \nVerwendung der -sOption unterstützt wird.
Eine Bash-Lösung, die sich gegenüber der @ osdyng-Antwort verbessert (meine Bearbeitung wurde nicht akzeptiert):
var="12345" rev=""
for(( i=0 ; i<${#var} ; i++ )); do rev="${var:i:1}$rev"; done
echo "var: $var, rev: $rev"
Oder eine noch einfachere (Bash-) Schleife:
var=$1 len="${#var}" i=0 rev=""
while (( i<len )); do rev="${var:i++:1}$rev"; done
echo "var: $var, rev: $rev"
Eine POSIX-Lösung:
var="12345" rev="" i=1
while [ "$i" -le "${#var}" ]
do rev="$(echo "$var" | awk -v i="$i" '{print(substr($0,i,1))}')$rev"
: $(( i+=1 ))
done
echo "var: $var, rev: $rev"
Hinweis: Dies funktioniert mit Multi-Byte-Zeichenfolgen. Schnittlösungen funktionieren nur in ASCII-Zeichenfolgen (1 Byte).
awk '{for(i=length($0);i;i--)printf "%s",substr($0,i,1); print ""}'oder sogarawk '{for(i=length($0);i;i--)x=x substr($0,i,1); print x}'
Dies kehrt die Zeichenfolge "an Ort und Stelle" um:
a=12345
len=${#a}
for ((i=1;i<len;i++)); do a=$a${a: -i*2:1}; done; a=${a:len-1}
echo $a
oder die dritte Zeile könnte sein:
for ((i=0;i<len;i++)); do a=${a:i*2:1}$a; done; a=${a:0:len}
oder
for ((i=1;i<len;i++)); do a=${a:0:len-i-1}${a: -i:i+1}${a:len-i-1:1}; done
Für diejenigen ohne rev (empfohlen) gibt es die folgende einfache awk- Lösung, die Felder in der Nullzeichenfolge aufteilt (jedes Zeichen ist ein separates Feld) und umgekehrt druckt:
awk -F '' '{ for(i=NF; i; i--) printf("%c", $i); print "" }'
Der obige awk- Code ist POSIX-kompatibel. Da eine kompatible awk- Implementierung garantiert auf jedem POSIX-kompatiblen Betriebssystem vorhanden ist, sollte die Lösung daher nicht als "Drittanbieter" betrachtet werden. Dieser Code ist wahrscheinlich prägnanter und verständlicher als eine reine POSIX sh (oder bash ) -Lösung.
(; Ich weiß nicht, ob Sie die Nullzeichenfolge für -F als regulären Ausdruck betrachten ...;)
Einige einfache Methoden zum Umkehren einer Zeichenfolge
echo '!!!esreveR si sihT' | grep -o . | tac | tr -d '\n' ; echo
echo '!!!esreveR si sihT' | fold -w 1 | tac | tr -d '\n' ; echo
In Hex-Werte konvertieren und dann umkehren
echo '!!!esreveR si sihT' | xxd -p | grep -o .. | tac | xxd -r -p ; echo
echo '!!!esreveR si sihT' | xxd -p | fold -w 2 | tac | xxd -r -p ; echo
Niemand scheint eine sedLösung veröffentlicht zu haben , daher hier eine, die in Nicht-GNU-Sed funktioniert (daher würde ich sie nicht als "Drittanbieter" betrachten). Es werden zwar einzelne Zeichen mit dem regulären Ausdruck erfasst ., dies ist jedoch der einzige reguläre Ausdruck.
In zwei Schritten:
$ echo 123456 | sed $'s/./&\\\n/g' | sed -ne $'x;H;${x;s/\\n//g;p;}'
654321
Dies verwendet die Ersetzung des Bash-Formats, um Zeilenumbrüche in die Skripte aufzunehmen (da die Frage markiert ist Bash). Es funktioniert, indem zuerst die Eingabezeichenfolge in eine Zeile pro Zeichen getrennt wird und dann jedes Zeichen am Anfang des Haltepuffers eingefügt wird.
x vertauscht den Haltebereich und den Musterbereich undH H hängt den (aktuellen) Musterraum an den Haltebereich an.Also platzieren wir dieses Zeichen für jedes Zeichen in den Haltebereich und hängen dann den alten Haltebereich an ihn an, wodurch die Eingabe umgekehrt wird. Der letzte Befehl entfernt die Zeilenumbrüche, um die ursprüngliche Zeichenfolge zu rekonstruieren.
Dies sollte für jede einzelne Zeichenfolge funktionieren, verkettet jedoch mehrzeilige Eingaben zu einer einzelnen Ausgabezeichenfolge.