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
sed
invocació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
zsh
en cuenta que (en lash
emulación),yash
y algunospdksh
shells basados no son POSIX en ese sentido, ya que se tratan$IFS
como 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
zsh
NUL 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; do
que 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 lazsh
misma (dividida en elementos de matriz, matriz inversa, elementos de matriz de combinación) pero utilizando operadores solo POSIX. (He cambiado elstring=$string$IFS; set -- $string
aset -- $string$IFS
ya 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
awk
respuesta, 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