¿Hay una manera simple de revertir una matriz?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
así que obtendría: en 7 6 5 4 3 2 1
lugar de:1 2 3 4 5 6 7
¿Hay una manera simple de revertir una matriz?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
así que obtendría: en 7 6 5 4 3 2 1
lugar de:1 2 3 4 5 6 7
He respondido la pregunta tal como está escrita, y este código invierte la matriz. (Imprimir los elementos en orden inverso sin invertir la matriz es solo un forciclo de cuenta regresiva desde el último elemento a cero). Este es un algoritmo estándar de "intercambio primero y último".
array=(1 2 3 4 5 6 7)
min=0
max=$(( ${#array[@]} -1 ))
while [[ min -lt max ]]
do
# Swap current first and last elements
x="${array[$min]}"
array[$min]="${array[$max]}"
array[$max]="$x"
# Move closer
(( min++, max-- ))
done
echo "${array[@]}"
Funciona para matrices de longitud impar y par.
Otro enfoque poco convencional:
Salida:
Si
extdebugestá habilitado, la matrizBASH_ARGVcontiene en una función todos los parámetros posicionales en orden inverso.fuente
Enfoque no convencional (todo no puro
bash):si todos los elementos en una matriz son solo un carácter (como en la pregunta) puede usar
rev:de otra manera:
y si puedes usar
zsh:fuente
tac, como lo opuesto acatbastante bueno para recordar, ¡GRACIAS!rev, necesito mencionar querevno funcionará correctamente para números con dos dígitos. Por ejemplo, un elemento de matriz de12usar rev se imprimirá como21. Pruébalo ;-)Si realmente quieres lo contrario en otra matriz:
Luego:
Da:
Esto debería manejar correctamente los casos en los que falta un índice de matriz, digamos que tenía
array=([1]=1 [2]=2 [4]=4), en cuyo caso el bucle de 0 al índice más alto puede agregar elementos adicionales vacíos.fuente
shellcheckimprime dos advertencias:array=(1 2 3 4)<-- SC2034: array appears unused. Verify it or export it.y para:echo "${foo[@]}"<-- SC2154: foo is referenced but not assigned.declarelínea.declare -nparece no funcionar en las versiones bash anteriores a 4.3.Para intercambiar las posiciones de la matriz en su lugar (incluso con matrices dispersas) (desde bash 3.0):
En ejecución:
Para bash más antiguo, debe usar un bucle (en bash (desde 2.04)) y usar
$apara evitar el espacio final:Para bash desde 2.03:
Además (usando el operador de negación bit a bit) (desde bash 4.2+):
fuente
Feo, imposible de mantener, pero de una sola línea:
fuente
eval eval echo "'\"\${array[-'{1..${#array[@]}}']}\"'".ind=("${!array[@]}");eval eval echo "'\"\${array[ind[-'{1..${#array[@]}}']]}\"'"Aunque no voy a decir algo nuevo y también lo usaré
tacpara revertir la matriz, creo que valdría la pena mencionar la siguiente solución de línea única con la versión bash 4.4:Pruebas:
Tenga en cuenta que el nombre de var dentro de read es el nombre de la matriz original, por lo que no se requiere una matriz auxiliar para el almacenamiento temporal.
Implementación alternativa ajustando IFS:
PD: Creo que las soluciones anteriores no funcionarán en la siguiente
bashversión4.4debido a la diferentereadimplementación de la función bash builtin.fuente
IFSversión funciona sino que también está imprimiendo:declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12"). Usando bash4.4-5. Debes eliminar;declare -p arrayal final de la primera línea, luego funciona ...declare -pes solo una forma rápida de hacer que bash imprima la matriz real (índice y contenido). No necesita estedeclare -pcomando en su script real. Si algo sale mal en las asignaciones de sus matrices, podría terminar en un caso que${array[0]}="1 2 3 4 5 6 10 11 12"= todos los valores almacenados en el mismo índice; usando echo no verá ninguna diferencia. Para una impresión de matriz rápida, usarádeclare -p arrayle devolverá las indeces de matriz real y el valor correspondiente en cada índice.read -d'\n'método no funcionó para ti?read -d'\n'funciona bien.Para invertir una matriz arbitraria (que puede contener cualquier número de elementos con cualquier valor):
Con
zsh:Con
bash4.4+, dado que lasbashvariables no pueden contener bytes NUL de todos modos, puede usar GNUtac -s ''en los elementos impresos como registros delimitados por NUL:POSIXly, para revertir la matriz de shell POSIX (
$@, hecha de$1,$2...):fuente
Solución de golpe puro, funcionaría como una sola línea.
fuente
rev+=( "${array[i]}" )parece más simple.también puedes considerar usar
seqen freebsd puede omitir -1 parámetro de incremento:
fuente
Golpetazo
O
Resultado
7 6 5 4 3 2 1
Versión
fuente
tacya se ha mencionado: unix.stackexchange.com/a/412874/260978 , unix.stackexchange.com/a/467924/260978 , unix.stackexchange.com/a/413176/260978