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' .