Jak sprawdzić, czy element znajduje się w tablicy bash?


15

Pomoc dla prostego skryptu

#!/bin/bash

array1=(
prova1
prova2
slack64
)

a="slack64"
b="ab"

if [ $a = $b ]
then
      echo "$a = $b : a is equal to b"
else
      echo "$a = $b: a is not equal to b"
fi

Ten skrypt po prostu nie działa, chcę skryptu, który sprawdza, czy slack64 jest obecny na liście (używam tablicy), i po prostu daje mi, tak, jest obecny lub nie. Nie wiem, jak porównać tablicę z jedną zmienną.


5
Gdzie array1działa?
tachomi

Odpowiedzi:


18

Użyj innego rodzaju tablicy: zamiast tablicy indeksowanej liczbami całkowitymi użyj tablicy asocjacyjnej, więc klucz (indeks) jest tym, czego będziesz szukał. bash-4.0lub później jest to wymagane.

declare -A array1=( 
 [prova1]=1  [prova2]=1  [slack64]=1
)

a=slack64
[[ -n "${array1[$a]}" ]] && printf '%s is in array\n' "$a"

W powyższym przypadku tak naprawdę nie dbamy o wartości, muszą one być tylko puste. Możesz „odwrócić” indeksowaną tablicę na nową tablicę asocjacyjną, wymieniając klucz i wartość:

declare -a array1=( 
 prova1 prova2 slack64
)
declare -A map    # required: declare explicit associative array
for key in "${!array1[@]}"; do map[${array1[$key]}]="$key"; done  # see below

a=slack64
[[ -n "${map[$a]}" ]] && printf '%s is in array\n' "$a"

Może się to opłacić, jeśli masz często wyszukiwane duże tablice, ponieważ implementacja tablic asocjacyjnych będzie działać lepiej niż pętle przeszukiwania tablic. Nie będzie pasował do każdego przypadku użycia, ponieważ nie może obsługiwać duplikatów (chociaż można użyć wartości jako licznika, zamiast tylko 1 jak powyżej) i nie może obsłużyć pustego indeksu.

Przełamując powyższą złożoną linię, aby wyjaśnić „inwersję”:

for key in "${!a[@]}"     # expand the array indexes to a list of words
do 
  map[${a[$key]}]="$key"  # exchange the value ${a[$key]} with the index $key
done

14

Najprostszym sposobem jest iteracja w pętli:

var=ab
for item in "${array[@]}"; do
    [[ $var == "$item" ]] && echo "$var present in the array"
done

? [[ a == aaa ]]jest fałszywe, ale dopasowanie aaa nie?
Gilles Quenot

W związku z tym PO należy poinformować, że musi uważać, czy wartości mogą zawierać znaki specjalne, takie jak [ ]: klasa postaci (globs)
Gilles Quenot

Nie widzę żadnej różnicy między = i == w bash [[ ]]dla tego, co powiedziałeś. Testowałeś?
Gilles Quenot,

2

Z zsh:

array1=(
  prova1
  prova2
  slack64
)

a=slack64

if ((array1[(Ie)$a])); then
  printf '%s\n' "$a in array1"
fi

2

Ta funkcja działa z tablicami asocjacyjnymi.

Możemy użyć tej funkcji, aby wykonać jedną z następujących czynności:

- sprawdź, czy tablica ma określony klucz -----------------> inArray „myKey” $ {! myArray [@]} ”

- sprawdź, czy tablica zawiera pewną wartość ---------> inArray „myValue” „$ {myArray [@]}”

function inArray # ( keyOrValue, arrayKeysOrValues ) 
{
  local e
  for e in "${@:2}"; do 
    [[ "$e" == "$1" ]] && return 0; 
  done
  return 1
}

declare -A arr
arr[doo]=55

inArray "doo" "${!arr[@]}"
echo $?     # 0 
inArray "bla" "${!arr[@]}"
echo $?     # 1 
inArray "55" "${arr[@]}"
echo $?     # 0

2

Możesz również użyć do tego grep:

array1 = (prova1 prova2 slack64)
a = slack64
if (printf '% s \ n' "$ {array1 [@]}" | grep -xq $ a); następnie
    echo „jest w”
fi

1
Zakłada się, że elementy tablicy nie zawierają znaków nowej linii (oraz spacji i symboli wieloznacznych, o których zapomniałeś cytować $a, i nie zaczynaj -od zapomnienia --). Możesz użyć %s\0zamiast %s\ni użyć grep --null(zakładając, że GNU grep lub zgodny), ponieważ zmienne bash i tak nie mogą zawierać znaku NUL. Trzeba by również specjalnie traktować przypadek pustej tablicy (ponieważ to polecenie printf wypisuje to samo, co w przypadku tablicy z jednym pustym elementem). Pamiętaj też, że nie musisz tutaj uruchamiać podpowłoki.
Stéphane Chazelas

tak, ma zastosowanie do prostych tablic takich jak ten w pytaniu.
Petr Ketner,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.