2011-05-02 8 views
9

¿Hay alguna forma de comprobar si una matriz contiene un elemento especificado?Operador de matriz en bash

por ejemplo, algo como:

array=(one two three) 

if [ "one" in ${array} ]; then 
... 
fi 

Respuesta

18

Un bucle hará el truco.

array=(one two three) 

for i in "${array[@]}"; do 
    if [[ "$i" = "one" ]]; then 
    ... 
    break 
    fi 
done 
+2

Bienvenido a SO Frank. Gran primera respuesta. – John

0
array="one two three" 
if [ $(echo "$array" | grep one | wc -l) -gt 0 ] ; 
    then echo yes; 
fi 

Si eso es feo, se podía esconderlo en una función.

+1

Si, por ejemplo, restriega los límites de las palabras, 'egrep" \ bone \ b "', evitará que array = "onex two three" coincida con 'uno'. '' echo "$ array" | egrep "\ bone \ b" && echo hit || echo miss'' es suficiente - wc-l y -gt0 es superfloo. –

+1

No hay necesidad de la prueba ('['). Solo usa el valor de retorno de grep. –

0

si sólo quiere comprobar si un elemento se encuentra en la matriz, otro enfoque

case "${array[@]/one/}" in 
"${array[@]}") echo "not in there";; 
*) echo "found ";; 
esac 
+1

¿No tiene el mismo problema que [esta respuesta] (http://stackoverflow.com/a/5853138/2533433) - es decir, echo "encontrado" también en "honesto"? 'foo = (hombre honesto); echo "$ {foo [@]/one /}" 'da' hst man', y así devolvería "encontrado" con su solución. – Izzy

5

Prueba esto:

array=(one two three) 
if [[ "${array[*]}" =~ "one" ]]; then 
    echo "'one' is found" 
fi 
+3

Eso funciona a menos que la matriz sea '' array = (scone honesto) ''que realmente no se puede decir que contenga un elemento' uno ', pero que se correspondería con el operador' = ~ '. –

+0

@Jonathan oops, tienes razón. Voto la respuesta de [@Frank] (http://stackoverflow.com/questions/5852446/in-array-operator-in-bash/5852473#5852473). – pepoluan

+0

Realmente no resuelve este problema * en general *, pero podría ser útil en muchos casos (al menos cuando cada elemento de la matriz consta de una sola palabra): hacer la expresión regular (derecha-sitio) '= ~" \ bone \ b " 'para unir palabras enteras solamente. ¡Me gusta la simplicidad! – Izzy

3

Tengo una función 'contiene' en mi .bashrc-archivo:

contains() 
{ 
    param=$1; 
    shift; 
    for elem in "[email protected]"; 
    do 
     [[ "$param" = "$elem" ]] && return 0; 
    done; 
    return 1 
} 

funciona bien con una matriz:

contains on $array && echo hit || echo miss 
    miss 
contains one $array && echo hit || echo miss 
    hit 
contains onex $array && echo hit || echo miss 
    miss 

pero no necesita una matriz:

contains one four two one zero && echo hit || echo miss 
    hit 
1

me gusta usar grep para esto:

if echo ${array[@]} | grep -qw one; then 
    # "one" is in the array 
    ... 
fi 

(Tenga en cuenta que tanto -q y -w son opciones no estándar a grep: -w le dice que funcione solo en palabras enteras, y -q ("silencioso") suprime toda la salida.)

+0

Tenga en cuenta que esto solo funciona si los elementos son palabras sueltas (como se indica en el ejemplo). Usarlo para verificar el elemento "uno" en 'matriz = (" un hombre "" dos caballos ")' sería erróneo ceder si (como "uno" es una palabra * contenida *, es decir, parte del primer elemento) , aunque no lo es (como elemento independiente). – Izzy

0
In_array() { 
    local NEEDLE="$1" 
    local ELEMENT 

    shift 

    for ELEMENT; do 
     if [ "$ELEMENT" == "$NEEDLE" ]; then 
      return 0 
     fi 
    done 

    return 1 
} 

declare -a ARRAY=("elem1" "elem2" "elem3") 
if In_array "elem1" "${ARRAY[@]}"; then 
... 

Una bonita y elegante versión de la anterior.