Existe-t-il un moyen simple d'inverser un tableau?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
donc j'obtiendrais: 7 6 5 4 3 2 1
au lieu de:1 2 3 4 5 6 7
Existe-t-il un moyen simple d'inverser un tableau?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
donc j'obtiendrais: 7 6 5 4 3 2 1
au lieu de:1 2 3 4 5 6 7
J'ai répondu à la question telle qu'elle est écrite, et ce code inverse le tableau. (L'impression des éléments dans l'ordre inverse sans inverser le tableau est juste une for
boucle à rebours du dernier élément à zéro.) Il s'agit d'un algorithme standard de «permutation du premier et du dernier».
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[@]}"
Cela fonctionne pour les tableaux de longueur paire et impaire.
Une autre approche non conventionnelle:
Production:
Si
extdebug
est activé, le tableauBASH_ARGV
contient dans une fonction tous les paramètres positionnels dans l'ordre inverse.la source
Approche non conventionnelle (toutes non pures
bash
):si tous les éléments d'un tableau ne sont qu'un seul caractère (comme dans la question), vous pouvez utiliser
rev
:autrement:
et si vous pouvez utiliser
zsh
:la source
tac
, comme le contraire decat
très bon à retenir, MERCI!rev
, je dois mentionner querev
cela ne fonctionnera pas correctement pour les numéros à deux chiffres. Par exemple, un élément de tableau12
utilisant rev sera imprimé sous la forme21
. Essayez-le ;-)Si vous voulez réellement l'inverse dans un autre tableau:
Alors:
Donne:
Cela devrait gérer correctement les cas où un index de tableau est manquant, par exemple
array=([1]=1 [2]=2 [4]=4)
, auquel cas une boucle de 0 à l'index le plus élevé peut ajouter des éléments vides supplémentaires.la source
shellcheck
imprime deux avertissements:array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
et:echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
declare
ligne.declare -n
ne semble pas fonctionner dans les versions bash antérieures à 4.3.Pour échanger les positions de tableau en place (même avec des tableaux clairsemés) (depuis bash 3.0):
À l'exécution:
Pour les bash plus anciens, vous devez utiliser une boucle (dans bash (depuis 2.04)) et utiliser
$a
pour éviter l'espace de fin:Pour bash depuis 2.03:
Aussi (en utilisant l'opérateur de négation au niveau du bit) (depuis bash 4.2+):
la source
Moche, impossible à entretenir, mais à une ligne:
la source
eval eval echo "'\"\${array[-'{1..${#array[@]}}']}\"'"
.ind=("${!array[@]}");eval eval echo "'\"\${array[ind[-'{1..${#array[@]}}']]}\"'"
Bien que je ne vais pas dire quelque chose de nouveau et que j'utiliserai également
tac
pour inverser le tableau, je pense que cela vaudrait la peine de mentionner une solution à une seule ligne en utilisant la version 4.4 de bash:Essai:
Gardez à l'esprit que le nom var à l'intérieur de read est le nom du tableau d'origine, donc aucun tableau d'assistance n'est requis pour le stockage temporaire.
Mise en œuvre alternative en ajustant IFS:
PS: Je pense que les solutions ci-dessus ne fonctionneront pas dans la
bash
version ci-dessous en4.4
raison de laread
mise en œuvre de la fonction intégrée bash différente .la source
IFS
version fonctionne , mais il est aussi l' impression:declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Utilisation de bash4.4-5
. Vous devez retirer;declare -p array
à la fin de la première ligne, alors ça marche ...declare -p
n'est qu'un moyen rapide de faire en sorte que bash imprime le vrai tableau (index et contenu). Vous n'avez pas besoin de cettedeclare -p
commande dans votre vrai script. Si quelque chose ne va pas dans vos affectations de tableaux, vous pourriez vous retrouver dans un cas qui${array[0]}="1 2 3 4 5 6 10 11 12"
= toutes les valeurs stockées dans le même index - en utilisant l'écho, vous ne verrez aucune différence. Pour une impression rapide du tableau à l'aide dedeclare -p array
, vous retournerez les véritables indecs du tableau et la valeur correspondante dans chaque index.read -d'\n'
méthode n'a pas fonctionné pour vous?read -d'\n'
fonctionne bien.Pour inverser un tableau arbitraire (qui peut contenir n'importe quel nombre d'éléments avec n'importe quelle valeur):
Avec
zsh
:Avec
bash
4.4+, étant donné que lesbash
variables ne peuvent de toute façon pas contenir d'octets NUL, vous pouvez utiliser GNUtac -s ''
sur les éléments imprimés en tant qu'enregistrements délimités NUL:POSIX, pour inverser le tableau shell POSIX (
$@
, composé de$1
,$2
...):la source
La solution Pure Bash fonctionnerait comme une doublure.
la source
rev+=( "${array[i]}" )
semble plus simple.vous pouvez également envisager d'utiliser
seq
dans freebsd, vous pouvez omettre le paramètre d'incrémentation -1:
la source
Frapper
Ou
Résultat
7 6 5 4 3 2 1
Version
la source
tac
a déjà été dit: unix.stackexchange.com/a/412874/260978 , unix.stackexchange.com/a/467924/260978 , unix.stackexchange.com/a/413176/260978