Si vous exécutez Bash version 4 ou supérieure (ce qui devrait être le cas dans n'importe quelle version moderne de Linux), vous pouvez obtenir des valeurs de tableau uniques dans bash en créant un nouveau tableau associatif contenant chacune des valeurs du tableau d'origine. Quelque chose comme ça:
$ a=(aa ac aa ad "ac ad")
$ declare -A b
$ for i in "${a[@]}"; do b["$i"]=1; done
$ printf '%s\n' "${!b[@]}"
ac ad
ac
aa
ad
Cela fonctionne car dans n'importe quel tableau (associatif ou traditionnel, dans n'importe quelle langue), chaque clé ne peut apparaître qu'une seule fois. Lorsque la for
boucle atteint la deuxième valeur de aa
in a[2]
, elle écrase la valeur b[aa]
initialement définie pour a[0]
.
Faire les choses en natif bash peut être plus rapide que d'utiliser des tubes et des outils externes comme sort
et uniq
, bien que pour des ensembles de données plus volumineux, vous obtiendrez probablement de meilleures performances si vous utilisez un langage plus puissant comme awk, python, etc.
Si vous vous sentez confiant, vous pouvez éviter la for
boucle en utilisant printf
la capacité de recycler son format pour plusieurs arguments, bien que cela semble être nécessaire eval
. (Arrêtez de lire maintenant si cela vous convient.)
$ eval b=( $(printf ' ["%s"]=1' "${a[@]}") )
$ declare -p b
declare -A b=(["ac ad"]="1" [ac]="1" [aa]="1" [ad]="1" )
La raison pour laquelle cette solution nécessite eval
est que les valeurs de tableau sont déterminées avant la division des mots. Cela signifie que la sortie de la substitution de commande est considérée comme un mot unique plutôt que comme un ensemble de paires clé = valeur.
Bien que cela utilise un sous-shell, il utilise uniquement des composants intégrés bash pour traiter les valeurs du tableau. Assurez-vous d'évaluer votre utilisation d' eval
un œil critique. Si vous n'êtes pas sûr à 100% que chepner, glenn jackman ou greycat ne trouveront aucun problème avec votre code, utilisez plutôt la boucle for.
uniq=($(printf "%s\n" "${ids[@]}" | sort -u)); echo "${uniq[@]}"