web-dev-qa-db-ja.com

一意の配列値を選択する方法は?

配列があり、ユニークな2番目のメンバーを取得したい

bashには実際には2次元配列がないため、2つの要素の区切り文字として::を使用して、このように定義しました。

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'
)

次の方法で、配列の2番目の要素を正常に反復できます。

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回だけ行うようにするにはどうすればよいですか?

つまり、配列の選択を(1.7.4 2.1.1)に変換するにはどうすればよいですか?

このコンテキストでは、実際のリポジトリ名は無視できます。

3
Michael Durrant

連想配列を使用できます。

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
2
glenn jackman
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"
1
Costas