Como selecionar valores de matriz exclusivos?

3

Eu tenho uma matriz e quero obter os únicos 2 membros

O

bash não tem realmente uma matriz bidimensional, por isso defini-o desta forma, usando :: como o separador dos dois elementos:

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

Eu posso iterar com sucesso os 2os elementos da matriz com:

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

A única desvantagem é que ele repete a ação quando a versão em ruby é a mesma (o que geralmente é o caso), então eu obtenho

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

quando tenho

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'

Como posso fazer isso, então só verifica a 1.7.4 e 2.1.1 uma vez?

i.e. Como posso transformar minha seleção de matriz em (1.7.4 2.1.1)

Os nomes reais do repositório podem ser ignorados neste contexto.

    
por Michael Durrant 10.11.2014 / 17:26

2 respostas

2

Você pode usar uma matriz associativa:

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

Ou com um pipeline:

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
    
por 10.11.2014 / 17:35
1
echo "${ruby_versions[@]}" | sed 's/\S\+:://g;s/\s\+/\n/g'| sort -u

saídas:

1.7.13
1.7.4
2.1.1

Ou se você quiser bash builtins

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