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 forboucle atteint la deuxième valeur de aain 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 sortet 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 forboucle en utilisant printfla 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 evalest 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' evalun œ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[@]}"