Tengo una cadena de entrada como:
arg1.arg2.arg3.arg4.arg5
La salida que quiero es:
arg5.arg4.arg3.arg2.arg1
No siempre son 5 argumentos, podría ser de 2 a 10.
¿Cómo puedo hacer esto en un script bash?
shell
text-processing
Jens
fuente
fuente

Si no le importa un poquito de
python:Ejemplo:
s.split(".")genera una lista que contiene.subcadenas separadas,[::-1]invierte la lista y".".join()une los componentes de la lista invertida con..fuente
Puedes hacerlo con una sola
sedinvocación:esto usa el búfer de retención para obtener una nueva línea inicial en el espacio del patrón y lo usa para realizar permutaciones hasta que la nueva línea ya no esté seguida de ningún punto en el punto en que elimine el punto inicial del espacio del patrón y reemplace la nueva línea con un punto.
Con BRE y una expresión regular ligeramente diferente:
Si la entrada consta de más de una línea y desea invertir el orden en cada línea:
fuente
Solución SED:
fuente
Con
zsh:Para preservar elementos vacíos:
s:.:: dividido en.Oa: Array especie a la inversa un RRay indice O rdenj:.:: únete..@: hacer una"$@"expansión similar a comillas dobles para que la expansión no se elimine en vacío.El POSIX (o
bash) equivalente podría ser algo como:(tenga
zshen cuenta que (en lashemulación),yashy algunospdkshshells basados no son POSIX en ese sentido, ya que se tratan$IFScomo un separador de campo en lugar de un delimitador de campo)Donde difiere de algunas de las otras soluciones dadas aquí es que no trata el carácter de nueva línea (y en el caso del
zshNUL tampoco) especialmente, eso se$'ab.cd\nef.gh'revertiría a$'gh.cd\nef.ab', no$'cd.ab\ngh.ef'o$'gh.ef.cd.ab'.fuente
IFS="."; set -f; set -- $string$IFS; for i; do rev="$i$IFS$rev"; done; printf '%s\n' "${rev%$IFS}"?for i; doque no es POSIX (todavía) incluso si es compatible con todos los shells POSIX que conozco). Es solo que esa solución es una traducción directa de lazshmisma (dividida en elementos de matriz, matriz inversa, elementos de matriz de combinación) pero utilizando operadores solo POSIX. (He cambiado elstring=$string$IFS; set -- $stringaset -- $string$IFSya que parece funcionar de manera consistente en todos los shells, gracias).Veo que Rahul ya publicó una solución bash nativa (entre otras), que es una versión más corta de la primera que se me ocurrió:
pero no pude parar allí, y sentí la necesidad de escribir una solución recursiva centrada en bash:
fuente
No vi una
awkrespuesta, así que aquí hay una:fuente
Pure Bash, requiere un período final en la entrada:
Use
printf %s "$g"si alguno de los elementos punteados podría comenzar con un guión.fuente