Respostas:
No Bash 4, você pode usar matrizes associativas:
# set up array of constants
declare -A array
for constant in foo bar baz
do
array[$constant]=1
done
# test for existence
test1="bar"
test2="xyzzy"
if [[ ${array[$test1]} ]]; then echo "Exists"; fi # Exists
if [[ ${array[$test2]} ]]; then echo "Exists"; fi # doesn't
Para configurar a matriz inicialmente, você também pode fazer atribuições diretas:
array[foo]=1
array[bar]=1
# etc.
ou desta maneira:
array=([foo]=1 [bar]=1 [baz]=1)
${array[$test1]}é simples, mas tem um problema: não funcionará se você usar set -useus scripts (o que é recomendado), pois você obteria "variável não acoplada".
É uma questão antiga, mas eu acho que é a solução mais simples ainda não apareceu: test ${array[key]+_}. Exemplo:
declare -A xs=([a]=1 [b]="")
test ${xs[a]+_} && echo "a is set"
test ${xs[b]+_} && echo "b is set"
test ${xs[c]+_} && echo "c is set"
Saídas:
a is set
b is set
Para ver como isso funciona, verifique isso .
envpara evitar ambiguidades em aliases, progs e outras funções que possam ter adotado o nome "teste". Como acima env test ${xs[a]+_} && echo "a is set". Você também pode obter essa funcionalidade usando colchetes duplos, o mesmo truque e depois verificando se [[ ! -z "${xs[b]+_}" ]] && echo "b is set"
[[ ${xs[b]+set} ]]
Existe uma maneira de testar se um elemento de uma matriz associativa existe (não definido), isso é diferente de vazio:
isNotSet() {
if [[ ! ${!1} && ${!1-_} ]]
then
return 1
fi
}
Então use-o:
declare -A assoc
KEY="key"
isNotSet assoc[${KEY}]
if [ $? -ne 0 ]
then
echo "${KEY} is not set."
fi
if ! some_check then return 1= some_check. Assim: isNotSet() { [[ ... ]] }. Confira minha solução abaixo, você pode fazer isso em uma verificação simples.
Você pode ver se uma entrada está presente canalizando o conteúdo da matriz para grep.
printf "%s\n" "${mydata[@]}" | grep "^${val}$"
Você também pode obter o índice de uma entrada com grep -n, que retorna o número da linha de uma correspondência (lembre-se de subtrair 1 para obter o índice baseado em zero). Isso será razoavelmente rápido, exceto para matrizes muito grandes.
# given the following data
mydata=(a b c "hello world")
for val in a c hello "hello world"
do
# get line # of 1st matching entry
ix=$( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 )
if [[ -z $ix ]]
then
echo $val missing
else
# subtract 1. Bash arrays are zero-based, but grep -n returns 1 for 1st line, not 0
echo $val found at $(( ix-1 ))
fi
done
a found at 0
c found at 2
hello missing
hello world found at 3
explicação:
$( ... ) é o mesmo que usar backticks para capturar a saída de um comando em uma variável printf gera mydata um elemento por linha @de *. evitar isso, dividem o "olá mundo" em duas linhas)greppesquisa a string exata: ^e $corresponde ao início e ao fim da linhagrep -n retorna a linha #, na forma de 4: hello world grep -m 1 encontra apenas a primeira correspondênciacut extrai apenas o número da linha Obviamente, você pode dobrar a subtração no comando. Mas, em seguida, teste -1 em falta:
ix=$(( $( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 ) - 1 ))
if [[ $ix == -1 ]]; then echo missing; else ... fi
$(( ... )) faz aritmética inteiraEu não acho que você pode fazê-lo corretamente sem fazer loop, a menos que tenha dados muito limitados na matriz.
Aqui está uma variante simples, isso diria corretamente que "Super User"existe na matriz. Mas também diria que "uper Use"está na matriz.
MyArray=('Super User' 'Stack Overflow' 'Server Fault' 'Jeff' );
FINDME="Super User"
FOUND=`echo ${MyArray[*]} | grep "$FINDME"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
#
# If you where to add anchors < and > to the data it could work
# This would find "Super User" but not "uper Use"
#
MyArray2=('<Super User>' '<Stack Overflow>' '<Server Fault>' '<Jeff>' );
FOUND=`echo ${MyArray2[*]} | grep "<$FINDME>"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
O problema é que não há uma maneira fácil de adicionar as âncoras (que eu possa pensar) além de percorrer o array. A menos que você possa adicioná-los antes de colocá-los na matriz ...
grep "\b$FINDME\b"). Provavelmente poderia trabalhar com constantes não alfanuméricos que não têm espaços, com "(^| )$FINDME(\$| )"(ou algo assim ... Eu nunca fui capaz de aprender o sabor de usos regexp grep.)
#!/bin/bash
function in_array {
ARRAY=$2
for e in ${ARRAY[*]}
do
if [[ "$e" == "$1" ]]
then
return 0
fi
done
return 1
}
my_array=(Drupal Wordpress Joomla)
if in_array "Drupal" "${my_array[*]}"
then
echo "Found"
else
echo "Not found"
fi
in_array. Cheers
${ARRAY[@]}deve ser usado.