Antworten:
Mit der Kombination von tr+ tac+paste
$ tr '.' $'\n' <<< 'arg1.arg2.arg3.arg4.arg5' | tac | paste -s -d '.'
arg5.arg4.arg3.arg2.arg1Wenn Sie immer noch Bash bevorzugen, können Sie auf diese Weise tun,
IFS=. read -ra line <<< "arg1.arg2.arg3.arg4."
let x=${#line[@]}-1;
while [ "$x" -ge 0 ]; do
echo -n "${line[$x]}.";
let x--;
doneVerwenden perl,
$ echo 'arg1.arg2.arg3.arg4.arg5' | perl -lne 'print join ".", reverse split/\./;'
arg5.arg4.arg3.arg2.arg1Wenn es Ihnen nichts ausmacht python:
".".join(s.split(".")[::-1])
Beispiel:
$ python3 -c 's="arg1.arg2.arg3.arg4.arg5"; print(".".join(s.split(".")[::-1]))'
arg5.arg4.arg3.arg2.arg1
s.split(".")generiert eine Liste mit .getrennten Teilzeichenfolgen, [::-1]kehrt die Liste um und ".".join()verbindet die Komponenten der umgekehrten Liste mit ..Sie können dies mit einem einzigen sedAufruf tun :
sed -E 'H;g;:t;s/(.*)(\n)(.*)(\.)(.*)/\1\4\5\2\3/;tt;s/\.(.*)\n/\1./'
Dies verwendet den Haltepuffer, um eine führende neue Zeile im Musterraum zu erhalten, und verwendet ihn, um Permutationen durchzuführen, bis auf die neue Zeile kein Punkt mehr folgt. An diesem Punkt wird der führende Punkt aus dem Musterraum entfernt und die neue Zeile durch einen Punkt ersetzt.
Mit BRE und einem etwas anderen Regex:
sed 'H
g
:t
s/\(.*\)\(\n\)\(.*\)\(\.\)\(.*\)/\1\4\5\2\3/
tt
s/\(\.\)\(.*\)\n/\2\1/'
Wenn die Eingabe aus mehr als einer Zeile besteht und Sie die Reihenfolge in jeder Zeile umkehren möchten:
sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/'
Mit zsh:
$ string=arg1.arg2.arg3.arg4.arg5
$ printf '%s\n' ${(j:.:)${(Oas:.:)string}}
arg5.arg4.arg3.arg2.arg1
So bewahren Sie leere Elemente auf:
$ string=arg1.arg2.arg3.arg4..arg5.
$ printf '%s\n' ${(j:.:)"${(@Oas:.:)string}"}
.arg5..arg4.arg3.arg2.arg1
s:.:: aufgeteilt auf .Oa: Sort Array in umgekehrter ein rray indice o rderj:.:: mach mit ..@: do- "$@"like-Erweiterung in doppelten Anführungszeichen, damit die Erweiterung nicht entleert wird.Das POSIX (oder bash) Äquivalent könnte etwa so lauten:
string=arg1.arg2.arg3.arg4..arg5.
IFS=.; set -f
set -- $string$IFS # split string into "$@" array
unset pass
for i do # reverse "$@" array
set -- "$i" ${pass+"$@"}
pass=1
done
printf '%s\n' "$*" # "$*" to join the array elements with the first
# character of $IFS
(Beachten Sie, dass zsh(in der shEmulation) yashund einige pdksh-basierte Shells in dieser Hinsicht keine POSIX-Shells sind, da sie $IFSals Feldtrennzeichen anstelle eines Feldtrennzeichens behandelt werden. )
Wo es sich von einigen anderen hier angegebenen Lösungen unterscheidet, ist, dass es das Newline-Zeichen (und im Falle des zshNUL- Zeichens auch nicht) nicht speziell behandelt, das heißt, es $'ab.cd\nef.gh'würde umgekehrt werden $'gh.cd\nef.ab', nicht $'cd.ab\ngh.ef'oder $'gh.ef.cd.ab'.
IFS="."; set -f; set -- $string$IFS; for i; do rev="$i$IFS$rev"; done; printf '%s\n' "${rev%$IFS}"?
for i; dodavon, dass es sich (noch) nicht um POSIX handelt, selbst wenn es von allen mir bekannten POSIX-Shells unterstützt wird). Es ist nur so, dass diese Lösung eine direkte Übersetzung der zsheinen Lösung ist (aufgeteilt in Array-, Reverse-Array- und Join-Array-Elemente), aber nur mit POSIX-Operatoren. (Ich habe die Einstellung auf geändert string=$string$IFS; set -- $string, set -- $string$IFSda dies über alle Shells hinweg konsistent zu funktionieren scheint, danke).
Ich sehe, Rahul hat (unter anderem) bereits eine native Bash-Lösung veröffentlicht, die eine kürzere Version der ersten ist, die ich mir ausgedacht habe:
function reversedots1() (
IFS=. read -a array <<<"$1"
new=${array[-1]}
for((i=${#array[*]} - 2; i >= 0; i--))
do
new=${new}.${array[i]}
done
printf '%s\n' "$new"
)
Aber ich konnte nicht damit aufhören und hatte das Bedürfnis, eine rekursive bash-zentrierte Lösung zu schreiben:
function reversedots2() {
if [[ $1 =~ ^([^.]*)\.(.*)$ ]]
then
printf %s $(reversedots2 "${BASH_REMATCH[2]}") . "${BASH_REMATCH[1]}"
else
printf %s "$1"
fi
}
Ich habe keine awkAntwort gefunden. Hier ist eine:
echo 'arg1.arg2.arg3' | awk -F. '{for (i=NF; i>0; --i) printf "%s%s", (i<NF ? "." : ""), $i; printf "\n"}'