Wenn Sie Bash Version 4 oder höher ausführen (was in jeder modernen Linux-Version der Fall sein sollte), können Sie eindeutige Array-Werte in bash erhalten, indem Sie ein neues assoziatives Array erstellen, das jeden der Werte des ursprünglichen Arrays enthält. Etwas wie das:
$ 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
Dies funktioniert, weil in jedem Array (assoziativ oder traditionell, in jeder Sprache) jeder Schlüssel nur einmal angezeigt werden kann. Wenn die forSchleife den zweiten Wert von aain erreicht a[2], überschreibt sie b[aa]den ursprünglich für a[0].
Das Ausführen von Dingen in nativem Bash kann schneller sein als das Verwenden von Pipes und externen Tools wie z. B. sortund uniqbei größeren Datensätzen werden Sie wahrscheinlich eine bessere Leistung erzielen, wenn Sie eine leistungsfähigere Sprache wie awk, python usw. verwenden.
Wenn Sie sich sicher fühlen, können Sie die forSchleife vermeiden , indem Sie die printfMöglichkeit nutzen, das Format für mehrere Argumente zu recyceln, obwohl dies anscheinend erforderlich ist eval. (Hör jetzt auf zu lesen, wenn du damit einverstanden bist.)
$ eval b=( $(printf ' ["%s"]=1' "${a[@]}") )
$ declare -p b
declare -A b=(["ac ad"]="1" [ac]="1" [aa]="1" [ad]="1" )
Der Grund, den diese Lösung erfordert, evalbesteht darin, dass Array-Werte vor der Wortteilung ermittelt werden. Dies bedeutet, dass die Ausgabe der Befehlssubstitution als einzelnes Wort und nicht als Satz von Schlüssel-Wert-Paaren betrachtet wird.
Während dies eine Subshell verwendet, werden nur Bash-Buildins verwendet, um die Array-Werte zu verarbeiten. Stellen Sie sicher, dass Sie Ihre Verwendung evalmit kritischem Auge bewerten . Wenn Sie nicht zu 100% sicher sind, dass chepner, glenn jackman oder greycat keinen Fehler an Ihrem Code finden, verwenden Sie stattdessen die for-Schleife.
uniq=($(printf "%s\n" "${ids[@]}" | sort -u)); echo "${uniq[@]}"