Entonces si tengo una variable
VAR='10 20 30 40 50 60 70 80 90 100'
y repetirlo
echo "$VAR"
10 20 30 40 50 60 70 80 90 100
Sin embargo, más abajo en el script, necesito invertir el orden de esta variable para que se muestre como algo así
echo "$VAR" | <code to reverse it>
100 90 80 70 60 50 40 30 20 10
Intenté usar rev y literalmente revirtió todo, así que salió como
echo "$VAR" | rev
001 09 08 07 06 05 04 03 02 01
Respuestas:
En los sistemas GNU, el reverso de cat es tac:
fuente
echo $'100 \n90 80 70 60 50 40 30 20 10'
tac -s" " <<< "$VAR "
versión actual , todavía inserta una línea en blanco inicial, agrega un espacio final y omite el carácter de nueva línea final (como si enprintf '\n%s ' "$reversed_VAR"
lugar de lo esperadoprintf '%s\n' "$reversed_VAR"
)echo $(tac -s" " <<< $VAR)
no tiene un espacio final porque$(…)
elimina las nuevas líneas y espacios finales si el IFS los tiene. Mi solución será corregida pronto, gracias.Para una lista corta, y en una variable, el shell en sí es la solución más rápida:
Salida:
Nota: la operación de división en
set -- $var
es segura para la cadena exacta utilizada aquí, pero no lo será si la cadena contiene caracteres comodín (*
,?
o[]
). Se puede evitarset -f
antes de la división, si es necesario. La misma nota también es válida para las siguientes soluciones (excepto donde se indique).O, si desea establecer alguna otra variable con la lista inversa:
O usando solo los parámetros posicionales.
O usando solo una variable (que puede ser var):
Nota: Esta solución no se ve afectada por el gloging ni IFS.
fuente
awk
al rescatecon
perl
, cortesía ¿Cómo leer una dirección IP al revés? compartido por @steeldriverO, consigo
bash
mismo al convertir la cadena en matrizfuente
Puede usar funciones bash como matrices para hacerlo completamente en proceso:
Esta debería ser la forma más rápida de hacerlo, siempre que $ VAR no sea muy grande.
fuente
VAR='+ * ?'
). Useset -o noglob
oset -f
para arreglar eso. En términos más generales, es una buena idea considerar el valor$IFS
y el estado de globing cuando se usa el operador split + glob. No es que tenga poco sentido usar ese operadorrev_a+=( ${a[$i]} )
,rev_a+=( "${a[$i]}" )
tendría mucho más sentido.fuente
Use un poco de magia Python aquí:
La forma en que esto funciona es bastante simple:
"$VAR"
como segundosys.argv[1]
parámetro de la línea de comando (el primer parámetro con-c
opción siempre es solo eso, en-c
sí mismo). Observe la cita"$VAR"
para evitar dividir la variable en palabras individuales (que hisi hizo por shell, no por python).split()
método, para dividirlo en una lista de cadenas[::-1]
parte es solo la sintaxis de corte extendida para obtener el reverso de la lista" ".join()
e imprimimosPero aquellos que no son grandes fanáticos de Python, podríamos
AWK
hacer esencialmente lo mismo: dividir e imprimir matriz en reversa:fuente
python3 -c 'import sys;print(*reversed(sys.argv[1:]))' $VAR
$IFS
contiene los caracteres adecuados y sin desactivar la parte glob."$VAR"
rendimientospython3 -c 'import sys;print(*reversed(sys.argv[1].split()))' "$VAR"
zsh
:$=VAR
se divide$VAR
en$IFS
.(Oa)
ordena la lista resultante en orden de matriz inversa.print -r --
(como enksh
), lo mismo queecho -E -
(zsh
específico) es una versión confiable deecho
: imprime sus argumentos tal como están separados por espacio, terminados por nueva línea.Si desea dividir solo en el espacio, y no en lo que sea que
$IFS
contenga (espacio, tabulación, nueva línea, nul por defecto), asigne espacio$IFS
o use una división explícita como:Para ordenar en orden numérico inverso:
POSIXly (también funcionaría con
bash
):Con
printf
mecanismos incorporados de shell (excepto en algunos shells) solamente (mejor para variables con un valor corto):Con
awk
(mejor para variables grandes, especialmente conbash
, pero hasta el límite del tamaño de los argumentos (o de un solo argumento)):fuente
Herramientas de software POSIX poco elegantes de una sola línea:
fuente