Bir öğenin bash dizisinde olup olmadığını nasıl test edebilirim?


15

Basit bir komut dosyası için yardım

#!/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

Bu komut dosyası işe yaramıyor, ben bir dizi (ben bir dizi kullanın) slack64 olup olmadığını kontrol bir komut dosyası istiyorum ve sadece bana vermek, evet, ya da hayır. Bir dizi tek bir değişken ile karşılaştırmak nasıl bilmiyorum.


5
İş nerede array1?
tachomi

Yanıtlar:


18

Farklı türde bir dizi kullanın: tamsayı dizine alınmış bir dizi yerine, ilişkilendirilebilir bir dizi kullanın, böylece anahtar (dizin) kontrol edeceğiniz şeydir. bash-4.0veya daha sonra bunun için gereklidir.

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

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

Yukarıda değerleri gerçekten önemsemiyoruz, sadece bunun için boş olmamaları gerekiyor. Anahtar ve değeri değiştirerek dizine alınmış bir diziyi yeni bir ilişkilendirilebilir diziye "tersine çevirebilirsiniz":

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"

İlişkilendirilebilir dizilerin uygulanması, dizi geçişli döngülerden daha iyi performans göstereceğinden, sık aranan büyük dizileriniz varsa, bu işe yarayabilir. Yinelenenleri işleyemediğinden (değeri yukarıdaki gibi yalnızca 1 yerine sayaç olarak kullanabilirsiniz) ve boş bir dizini işleyemediği için her kullanım durumuna uygun olmaz.

"Ters çevirme" yi açıklamak için yukarıdaki karmaşık çizgiyi kırmak:

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

En basit yol, bir döngü ile yineleme yapmaktır:

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

? [[ a == aaa ]]yanlış ama bir eşleştirme aaa hayır?
Gilles Quenot

Bu yüzden OP, değerlerin özel karakterler içerebileceğine dikkat etmesi gerektiği konusunda bilgilendirilmelidir, örneğin [ ]: karakter sınıfı (globs)
Gilles Quenot

[[ ]]Söyledikleriniz için bash = ve == arasında bir fark görmüyorum . Test yaptın mı?
Gilles Quenot

2

İle zsh:

array1=(
  prova1
  prova2
  slack64
)

a=slack64

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

2

Bu işlev ilişkilendirilebilir dizilerle çalışır.

Bu işlevi aşağıdakilerden birini yapmak için kullanabiliriz:

- dizinin belirli bir anahtarı olup olmadığını kontrol edin -----------------> inArray "myKey" $ {! myArray [@]} "

- dizinin belirli bir değer içerip içermediğini kontrol edin ---------> 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

Bunun için grep'i de kullanabilirsiniz:

dizi1 = (prova1 prova2 boşluğu64)
a = slack64
if (printf '% s \ n' "$ {dizi1 [@]}" | grep -xq $ a); sonra
    echo "içeride"
fi

1
Bu, dizi öğelerinin yeni satır karakterleri içermediğini (ve alıntı yapmayı unuttuğunuzda boşluklar ve joker karakterler içerdiğini ve unuttuğunuz gibi $abaşlamadığını) varsayar . Bash değişkenleri zaten NUL karakterini içeremediğinden (GNU grep veya uyumlu olduğunu varsayarak) kullanmak yerine kullanabilirsiniz . Ayrıca, boş bir dizinin durumunu özel olarak ele almanız gerekir (çünkü printf komutu, boş bir öğeye sahip bir diziyle aynı şeyi yazdırır). Ayrıca burada bir alt kabuk başlatmanız gerekmediğini unutmayın. ---%s\0%s\ngrep --null
Stéphane Chazelas

evet, söz konusu gibi basit dizilere uygulanabilir.
Petr Ketner
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.