Jeśli używasz Bash w wersji 4 lub nowszej (co powinno mieć miejsce w każdej nowoczesnej wersji Linuksa), możesz uzyskać unikalne wartości tablic w bash, tworząc nową tablicę asocjacyjną zawierającą każdą z wartości oryginalnej tablicy. Coś takiego:
$ 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
To działa, ponieważ w dowolnej tablicy (asocjacyjnej lub tradycyjnej, w dowolnym języku) każdy klucz może wystąpić tylko raz. Kiedy forpętla osiąga drugą wartość aain a[2], nadpisuje b[aa]pierwotnie ustawioną wartość a[0].
Robienie rzeczy w natywnym bashu może być szybsze niż używanie potoków i zewnętrznych narzędzi, takich jak sorti uniq, chociaż w przypadku większych zestawów danych prawdopodobnie zobaczysz lepszą wydajność, jeśli użyjesz mocniejszego języka, takiego jak awk, python itp.
Jeśli czujesz się pewnie, możesz uniknąć forpętli, korzystając printfz możliwości ponownego wykorzystania formatu dla wielu argumentów, chociaż wydaje się to wymagać eval. (Przestań czytać teraz, jeśli nie masz nic przeciwko.)
$ eval b=( $(printf ' ["%s"]=1' "${a[@]}") )
$ declare -p b
declare -A b=(["ac ad"]="1" [ac]="1" [aa]="1" [ad]="1" )
Powodem, dla którego to rozwiązanie wymaga, evaljest to, że wartości tablic są określane przed podziałem na słowa. Oznacza to, że wynik podstawienia polecenia jest traktowany jako pojedyncze słowo a nie zestaw par klucz = wartość.
Chociaż używa podpowłoki, używa tylko wbudowanych bash do przetwarzania wartości tablic. Pamiętaj, aby evalkrytycznym okiem ocenić swoje użycie . Jeśli nie masz 100% pewności, że chepner, glenn jackman lub greycat nie znajdzie żadnych błędów w twoim kodzie, użyj zamiast tego pętli for.
uniq=($(printf "%s\n" "${ids[@]}" | sort -u)); echo "${uniq[@]}"