Bash sürüm 4 veya üzerini çalıştırıyorsanız (Linux'un herhangi bir modern sürümünde durum böyle olmalıdır), orijinal dizinin her bir değerini içeren yeni bir ilişkilendirilebilir dizi oluşturarak bash'de benzersiz dizi değerleri elde edebilirsiniz. Bunun gibi bir şey:
$ 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
Bu işe yarar çünkü herhangi bir dizide (ilişkisel veya geleneksel, herhangi bir dilde), her anahtar yalnızca bir kez görünebilir. Zaman for
döngü ikinci değere ulaşır aa
in a[2]
, bu yazar b[aa]
için, esas olarak ayarlanmış edildi a[0]
.
Yerli bash Uyguluyor boru ve benzeri dış araçlarını kullanarak daha hızlı olabilir sort
ve uniq
vb awk, piton, gibi daha güçlü bir dil kullanmak durumunda daha büyük veri kümeleri için büyük olasılıkla daha iyi performans görürler,
Kendinizden emin hissediyorsanız, 'nın biçimini birden çok argüman için geri dönüştürme yeteneğini for
kullanarak döngüden kaçınabilirsiniz printf
, ancak bu gerektiriyor gibi görünüyor eval
. (Bunda sorun yoksa şimdi okumayı bırak.)
$ eval b=( $(printf ' ["%s"]=1' "${a[@]}") )
$ declare -p b
declare -A b=(["ac ad"]="1" [ac]="1" [aa]="1" [ad]="1" )
Bu çözümün gerektirmesinin nedeni eval
, dizi değerlerinin kelime bölünmeden önce belirlenmesidir. Bu, komut ikamesinin çıktısının bir anahtar = değer çifti kümesi yerine tek bir kelime olarak kabul edildiği anlamına gelir .
Bu bir alt kabuk kullanırken, dizi değerlerini işlemek için yalnızca bash yerleşiklerini kullanır. Kullanımınızı eval
eleştirel bir gözle değerlendirdiğinizden emin olun . Chepner veya glenn jackman veya greycat'ın kodunuzda herhangi bir hata bulmayacağından% 100 emin değilseniz, bunun yerine for döngüsünü kullanın.
uniq=($(printf "%s\n" "${ids[@]}" | sort -u)); echo "${uniq[@]}"