Jika Anda menjalankan Bash versi 4 atau lebih tinggi (yang seharusnya terjadi pada versi Linux modern), Anda bisa mendapatkan nilai array unik di bash dengan membuat array asosiatif baru yang berisi setiap nilai dari array asli. Sesuatu seperti ini:
$ 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
Ini berfungsi karena dalam larik apa pun (asosiatif atau tradisional, dalam bahasa apa pun), setiap kunci hanya dapat muncul sekali. Ketika forperulangan tiba di nilai kedua dari aadalam a[2], itu menimpa b[aa]yang awalnya ditetapkan untuk a[0].
Melakukan hal-hal di bash asli bisa lebih cepat daripada menggunakan pipa dan alat eksternal seperti sortdan uniq, meskipun untuk kumpulan data yang lebih besar Anda kemungkinan akan melihat kinerja yang lebih baik jika Anda menggunakan bahasa yang lebih kuat seperti awk, python, dll.
Jika Anda merasa yakin, Anda dapat menghindari forpengulangan dengan menggunakan printfkemampuan untuk mendaur ulang formatnya untuk beberapa argumen, meskipun ini tampaknya membutuhkan eval. (Berhenti membaca sekarang jika Anda setuju dengan itu.)
$ eval b=( $(printf ' ["%s"]=1' "${a[@]}") )
$ declare -p b
declare -A b=(["ac ad"]="1" [ac]="1" [aa]="1" [ad]="1" )
Alasan yang dibutuhkan oleh solusi ini evaladalah karena nilai array ditentukan sebelum pemisahan kata. Itu berarti bahwa output dari substitusi perintah dianggap sebagai kata tunggal daripada sekumpulan pasangan kunci = nilai.
Meskipun ini menggunakan subkulit, ini hanya menggunakan bash bawaan untuk memproses nilai array. Pastikan untuk mengevaluasi penggunaan Anda evaldengan mata kritis. Jika Anda tidak 100% yakin bahwa chepner atau glenn jackman atau greycat tidak akan menemukan kesalahan pada kode Anda, gunakan loop for sebagai gantinya.
uniq=($(printf "%s\n" "${ids[@]}" | sort -u)); echo "${uniq[@]}"