J'essaie de collecter des valeurs de chaîne dans un script bash. Quel est le moyen le plus simple d'ajouter des valeurs de chaîne à une structure de liste ou de tableau de manière à pouvoir les répercuter à la fin?
$ arr=(1 2 3)
$ arr+=(4)
$ echo ${arr[@]}
1 2 3 4
Etant donné que Bash utilise des tableaux fragmentés, vous ne devez pas utiliser le nombre d'éléments ${#arr}
comme index. Vous pouvez cependant obtenir un tableau d'indices comme celui-ci:
$ indices=(${!arr[@]})
foo=(a b c)
foo=("${foo[@]}" d)
for i in "${foo[@]}"; do echo "$i" ; done
$ for i in "string1" "string2" "string3"
> do
> array+=($i)
> done
$ echo ${array[@]}
string1 string2 string3
La syntaxe assez obscure pour ajouter à la fin d'un tableau dans bash est la suivante:
myarr[${#myarr[*]}]=”$newitem”
Pour ajouter à ce qu'Ignacio a suggéré dans une autre réponse:
foo=(a b c)
foo=("${foo[@]}" d) # Push element 'd'
foo[${#foo[*]}]="e" # Push element 'e'
for i in "${foo[@]}"; do echo "$i" ; done
Bien que la question ait reçu une réponse et qu'elle soit assez ancienne, j'aimerais partager une solution d'espace de noms, car elle fonctionne beaucoup plus rapidement que toute autre méthode, à l'exception de la réponse de ennukiller (mes tests sur 100 000 lignes ont permis de gagner environ 12 secondes contre mes ~ 14 secondes, alors que la solution liste-append prend quelques minutes).
Vous pouvez utiliser le truc suivant:
# WORKS FASTER THAN THESE LAME LISTS! ! !
size=0;while IFS= read -r line; do
echo $line
((++size))
eval "SWAMP_$size='$line'"
done
Ou vous pouvez faire ce qui suit:
#!/bin/bash
size=0
namespace="SWAMP"
ArrayAppend() {
namespace="$1"
# suppose array size is global
new_value="$2"
eval "${namespace}_$size='$2'"
eval "echo \$${namespace}_$size"
((++size))
}
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
Tant que l'interprète est dans la liste des balises, voici un lien pour orienté objet bash .