121 votes

Comment copier un tableau en Bash?

J'ai un tableau d'applications, initialisé comme ceci :

depends=$(cat ~/Depends.txt)

Lorsque j'essaie de parcourir la liste et de la copier dans un nouveau tableau en utilisant,

for i in "${depends[@]}"; do
   if [ $i #n'est pas installé ]; then
      newDepends+=("$i")
   fi
done

Ce qui se passe, c'est que seul le premier élément de depends finit sur newDepends.

for i in "${newDepends[@]}"; do
   echo $i
done

^^ Cela afficherait juste une chose. Je cherche donc à comprendre pourquoi ma boucle for ne déplace que le premier élément. Toute la liste est à l'origine sur depends, donc ce n'est pas ça, mais je suis à court d'idées.

202voto

user1088530 Points 1624
a=(foo bar "foo 1" "bar two")  #créer un tableau
b=("${a[@]}")                  #copier le tableau dans un autre 

for value in "${b[@]}" ; do    #afficher le nouveau tableau 
echo "$value" 
done

61voto

NIXin Points 44

La manière la plus simple de copier un tableau non associatif en bash est de :

arrayClone=("${oldArray[@]}")

ou pour ajouter des éléments à un tableau préexistant :

someArray+=("${oldArray[@]}")

Les sauts de ligne/espaces/IFS dans les éléments seront préservés.

Pour copier des tableaux associatifs, les solutions d'Isaac fonctionnent très bien.

12voto

Isaac Schwabacher Points 129

Les solutions proposées dans les autres réponses ne fonctionneront pas pour les tableaux associatifs, ni pour les tableaux avec des indices non contigus. Voici une solution plus générale :

declare -A arr=([this]=hello ['that']=world [theother]='and "goodbye"!')
temp=$(declare -p arr)
eval "${temp/arr=/newarr=}"

diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/')
# pas de sortie

Et un autre :

declare -A arr=([this]=hello ['that']=world [theother]='and "goodbye"!')
declare -A newarr
for idx in "${!arr[@]}"; do
    newarr[$idx]=${arr[$idx]}
done

diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/')
# pas de sortie

7voto

maheshk Points 79

Essayez ceci : arrayClone=("${oldArray[@]}")

Cela fonctionne facilement.

4voto

flabdablet Points 1066
array_copy() {
    set -- "$(declare -p $1)" "$2"
    eval "$2=${1#*=}"
}

# Exemples d'utilisation :

these=(pomme banane catalogue dormant aigle fruit oie chapeau glaçon)
array_copy these those
declare -p those

declare -A src dest
source=(["C'est un 15\" clou"]="et il fait 1\" d'épaisseur" [foo]=bar [baz]=qux)
array_copy src dest
declare -p dest

Note : lors de la copie de tableaux associatifs, la destination doit déjà exister en tant que tableau associatif. Sinon, array_copy() le créera en tant que tableau standard et tentera d'interpréter les noms de clé de la source associative comme des noms de variables arithmétiques, avec des résultats laids.

La solution de Isaac Schwabacher est plus robuste à cet égard, mais elle ne peut pas être proprement enveloppée dans une fonction car son étape eval évalue une déclaration entière et Bash les traite comme équivalents à local lorsqu'ils sont à l'intérieur d'une fonction. Cela pourrait être contourné en insérant l'option -g dans la déclaration évaluée, mais cela pourrait donner au tableau de destination plus de portée que prévu. Mieux, je pense, que array_copy() effectue seulement la copie réelle dans une destination explicitement portée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X