Bash

如何選擇唯一的數組值?

  • November 10, 2014

我有一個數組,我想獲得唯一的第二個成員

bash 並沒有真正的二維數組,所以我這樣定義它,::用作兩個元素的分隔符:

ruby_versions=(
'company-contacts::1.7.4'
'activerecord-boolean-converter::1.7.4'
'zipcar-rails-core::1.7.4'
'async-tasks::1.7.13'
'zc-pooling-client::2.1.1'
'reservations-api::1.7.4'
'zipcar-auth-gem::1.7.4'
'members-api::1.7.4'
'authentication-service::1.7.4'
'pooling-api::2.1.1'
)

我可以通過數組的第二個元素成功迭代:

rvm list > $TOP_DIR/local_ruby_versions.txt

for repo in "${ruby_versions[@]}"
do
 if grep -q "${repo##*::}" $TOP_DIR/local_ruby_versions.txt
   then
   echo "ruby version ${repo##*::} confirmed as present on this machine"
 else
   rvm list
   echo "*** EXITING SMOKE TEST *** - not all required ruby versions are present in RVM"
   echo "Please install RVM ruby version: ${repo##*::} and then re-run this program"
   exit 0
 fi
done
echo "A

唯一的缺點是它在 ruby​​ 版本相同時重複操作(通常是這種情況),所以我得到

ruby version 1.7.4 confirmed as present on this machine
ruby version 1.7.4 confirmed as present on this machine
ruby version 1.7.4 confirmed as present on this machine
ruby version 1.7.13 confirmed as present on this machine
ruby version 2.1.1 confirmed as present on this machine
ruby version 1.7.4 confirmed as present on this machine
ruby version 1.7.4 confirmed as present on this machine
ruby version 1.7.4 confirmed as present on this machine
ruby version 1.7.4 confirmed as present on this machine
ruby version 2.1.1 confirmed as present on this machine

當我有

ruby_versions=(
 'company-contacts::1.7.4'
 'activerecord-boolean-converter::1.7.4'
 'zipcar-rails-core::1.7.4'
 'async-tasks::1.7.13'
 'zc-pooling-client::2.1.1'
 'reservations-api::1.7.4'
 'zipcar-auth-gem::1.7.4'
 'members-api::1.7.4'
 'authentication-service::1.7.4'
 'pooling-api::2.1.1'

)

我怎樣才能使它只檢查 1.7.4 和 2.1.1 一次?

即如何將我的數組選擇變成(1.7.4 2.1.1)

在這種情況下,可以忽略實際的 repo 名稱。

您可以使用關聯數組:

declare -A versions
for value in "${ruby_versions[@]}"; do
   versions["${value##*::}"]=1
done
printf "%s\n" "${!versions[@]}"
1.7.4
1.7.13
2.1.1

或使用管道:

mapfile -t versions < <(printf "%s\n" "${ruby_versions[@]}" | sed 's/.*:://' | sort -u)
printf "%s\n" "${versions[@]}"
1.7.13
1.7.4
2.1.1
echo "${ruby_versions[@]}" | sed 's/\S\+:://g;s/\s\+/\n/g'| sort -u

輸出:

1.7.13
1.7.4
2.1.1

或者如果你願意bash builtins

unset u
for i in "${ruby_versions[@]}"
do
 if [[ ! $u =~ ${i##*::} ]]
 then
   u=${u:+$u\\n}${i##*::}
 fi
done
echo -e "$u"

引用自:https://unix.stackexchange.com/questions/167140