com zsh
:
$ string=arg1.arg2.arg3.arg4.arg5
$ printf '%s\n' ${(j:.:)${(Oas:.:)string}}
arg5.arg4.arg3.arg2.arg1
Para preservar elementos vazios:
$ string=arg1.arg2.arg3.arg4..arg5.
$ printf '%s\n' ${(j:.:)"${(@Oas:.:)string}"}
.arg5..arg4.arg3.arg2.arg1
-
s:.:
: dividido em .
-
Oa
: sort array no reverso a rice o rder
-
j:.:
: junte-se a .
.
-
@
: do "$@"
-like expansion quando estiver entre aspas duplas, portanto a expansão não sofrerá remoção vazia.
O equivalente POSIX (ou bash
) poderia ser algo como:
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
(observe que zsh
(em sh
emulation), yash
e alguns pdksh
-shells baseados não são POSIX a esse respeito, pois tratam $IFS
como um separador de campo em vez de um delimitador de campo)
Onde ele difere de algumas das outras soluções dadas aqui é que ele não trata o caractere de nova linha (e, no caso de zsh
, o NUL também), especialmente, que é $'ab.cd\nef.gh'
seria revertido para $'gh.cd\nef.ab'
, não $'cd.ab\ngh.ef'
ou $'gh.ef.cd.ab'
.