Bagaimana cara menguji jika suatu item ada dalam bash array?


15

Bantuan untuk skrip sederhana

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

Skrip ini tidak berfungsi, saya ingin skrip yang memeriksa apakah slack64 ada dalam daftar (saya menggunakan array), dan cukup beri saya, ya ada, atau tidak. Saya tidak tahu bagaimana membandingkan array dengan satu variabel.


4
Di mana array1pekerjaannya?
tachomi

Jawaban:


17

Gunakan berbagai jenis array: daripada array yang diindeks integer, gunakan array asosiatif, jadi kuncinya (indeks) adalah apa yang akan Anda periksa. bash-4.0atau lambat diperlukan untuk ini.

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

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

Di atas kita tidak terlalu peduli dengan nilai-nilai, mereka hanya perlu kosong untuk ini. Anda dapat "membalikkan" array yang diindeks ke dalam array asosiatif baru dengan menukar kunci dan nilai:

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"

Ini dapat membuahkan hasil jika Anda memiliki array besar yang sering dicari, karena penerapan array asosiatif akan lebih baik daripada loop array-traversing. Itu tidak akan cocok dengan setiap kasus penggunaan, karena tidak dapat menangani duplikat (meskipun Anda dapat menggunakan nilai sebagai penghitung, bukan hanya 1 seperti di atas), dan tidak dapat menangani indeks kosong.

Hancurkan garis kompleks di atas, untuk menjelaskan "inversi":

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

Cara langsung adalah beralih dengan loop:

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

? [[ a == aaa ]]itu salah tapi kecocokan aaa tidak?
Gilles Quenot

JADI OP harus diberitahu bahwa dia harus berhati-hati jika nilai-nilai dapat mengandung karakter khusus, seperti [ ]: kelas karakter (gumpalan)
Gilles Quenot

Saya tidak melihat perbedaan antara = dan == di bash [[ ]]untuk apa yang Anda katakan. Sudahkah Anda menguji?
Gilles Quenot

2

Dengan zsh:

array1=(
  prova1
  prova2
  slack64
)

a=slack64

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

2

Fungsi ini berfungsi dengan array asosiatif.

Kita dapat menggunakan fungsi ini untuk melakukan salah satu dari yang berikut:

- periksa apakah array memiliki kunci tertentu -----------------> inArray "myKey" $ {! myArray [@]} "

- periksa apakah array mengandung nilai tertentu ---------> 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

Anda juga dapat menggunakan grep untuk itu:

array1 = (prova1 prova2 slack64)
a = slack64
if (printf '% s \ n' "$ {array1 [@]}" | grep -xq $ a); kemudian
    gema "ada di"
fi

1
Itu mengasumsikan elemen array tidak mengandung karakter baris baru (dan kosong dan wildcard saat Anda lupa mengutip $a, dan jangan mulai dengan -ketika Anda lupa --). Anda bisa menggunakan %s\0alih-alih %s\ndan menggunakan grep --null(dengan asumsi GNU grep atau kompatibel) sebagai variabel bash tidak bisa mengandung karakter NUL. Anda juga perlu menangani case dari array kosong secara khusus (karena perintah printf akan mencetak hal yang sama seperti untuk array dengan satu elemen kosong). Perhatikan juga bahwa Anda tidak perlu memulai subkulit di sini.
Stéphane Chazelas

ya, itu berlaku pada array sederhana seperti yang ada di pertanyaan.
Petr Ketner
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.