ฉันจะทดสอบว่ารายการอยู่ในอาร์เรย์ทุบตีได้อย่างไร


15

ช่วยสคริปต์ง่าย ๆ

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

สคริปต์นี้ใช้งานไม่ได้ฉันต้องการสคริปต์ที่ตรวจสอบว่า slack64 มีอยู่ในรายการ (ฉันใช้อาร์เรย์) และให้ฉันใช่มีอยู่หรือไม่ ฉันไม่รู้วิธีเปรียบเทียบอาเรย์กับตัวแปรตัวเดียว


5
ในกรณีที่ไม่array1ทำงานหรือไม่
ทาโชมิ

คำตอบ:


17

ใช้อาเรย์ประเภทอื่น: แทนที่จะเป็นอาเรย์แบบจำนวนเต็มใช้อาเรย์แบบเชื่อมโยงดังนั้นคีย์ (ดัชนี) คือสิ่งที่คุณจะตรวจสอบ bash-4.0หรือหลังจากนั้นจำเป็นสำหรับสิ่งนี้

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

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

ในตัวอย่างข้างต้นเราไม่สนใจค่านิยมเหล่านี้ แต่อย่างใดพวกเขาต้องไม่ว่างเปล่าสำหรับสิ่งนี้ คุณสามารถ "สลับ" อาเรย์ที่จัดทำดัชนีไว้ในอาเรย์แบบเชื่อมโยงใหม่โดยการแลกเปลี่ยนคีย์และค่า:

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"

สิ่งนี้สามารถชำระได้ถ้าคุณมีอาร์เรย์ขนาดใหญ่ที่ถูกค้นหาบ่อยๆเนื่องจากการใช้อาร์เรย์ที่เชื่อมโยงจะทำงานได้ดีกว่าลูปการสำรวจอาร์เรย์ มันจะไม่เหมาะกับทุกกรณีการใช้งานเพราะมันไม่สามารถจัดการรายการที่ซ้ำกัน (แม้ว่าคุณสามารถใช้ค่าเป็นตัวนับแทนที่จะเป็นเพียง 1 ข้างต้น) และมันไม่สามารถจัดการกับดัชนีที่ว่างเปล่า

แยกบรรทัดที่ซับซ้อนด้านบนเพื่ออธิบาย "การผกผัน":

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

วิธีที่ตรงไปตรงมาคือวนซ้ำกับลูป:

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

? [[ a == aaa ]]เป็นเท็จ แต่การแข่งขัน aaa ไม่ใช่
Gilles Quenot

ดังนั้น OP ควรได้รับแจ้งว่าเขาจะต้องดูแลหากค่าสามารถมีอักขระพิเศษเช่น[ ]: คลาสของตัวละคร (globs)
Gilles Quenot

ฉันไม่เห็นความแตกต่างระหว่าง = และ == ในการทุบตี[[ ]]สิ่งที่คุณพูด คุณผ่านการทดสอบแล้วหรือยัง
Gilles Quenot


2

ฟังก์ชั่นนี้ทำงานร่วมกับอาร์เรย์ที่เชื่อมโยงกัน

เราสามารถใช้ฟังก์ชั่นนี้เพื่อทำสิ่งใดสิ่งหนึ่งต่อไปนี้:

- ตรวจสอบว่าอาร์เรย์มีคีย์ที่แน่นอนหรือไม่ -----------------> inArray "myKey" $ {! myArray [@]} "

- ตรวจสอบว่าอาร์เรย์มีค่าที่แน่นอน ---------> 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

คุณยังสามารถใช้ grep เพื่อ:

array1 = (prova1 prova2 slack64)
A = slack64
if (printf '% s \ n' "$ {array1 [@]}" | grep -xq $ a); แล้วก็
    echo "มันอยู่ใน"
Fi

1
ซึ่งถือว่าองค์ประกอบอาร์เรย์ไม่มีอักขระขึ้นบรรทัดใหม่ (และช่องว่างและอักขระตัวแทนในขณะที่คุณลืมที่จะพูด$aและอย่าเริ่มต้นด้วย-เมื่อคุณลืม--) คุณสามารถใช้%s\0แทน%s\nและใช้grep --null(สมมติว่า grep GNU หรือเทียบเท่า) เนื่องจากตัวแปร bash ไม่สามารถมีอักขระ NUL อยู่ดี คุณจะต้องจัดการกับกรณีของอาเรย์ที่ว่างเปล่าเป็นพิเศษ (เช่นคำสั่ง printf จะพิมพ์สิ่งเดียวกันกับอาเรย์ที่มีองค์ประกอบหนึ่งที่ว่างเปล่า) นอกจากนี้โปรดทราบว่าคุณไม่จำเป็นต้องเริ่ม subshell ที่นี่
Stéphane Chazelas

ใช่มันใช้ได้กับอาร์เรย์อย่างง่ายเช่นเดียวกับคำถาม
Petr Ketner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.