Bash 배열에 값이 포함되어 있는지 확인하는 방법

Bash 배열에 값이 포함되어 있는지 확인하는 방법

간단한 스크립트로 도움말

#!/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가 목록에 있는지 확인하고(저는 배열을 사용하고 있습니다), 그것이 존재하는지 또는 존재하지 않는지 간단히 알려주는 스크립트가 필요합니다. 배열을 단일 변수와 비교하는 방법을 모르겠습니다.

답변1

다른 유형의 배열을 사용하십시오. 정수 인덱스 배열 대신 연관 배열을 사용하십시오. 따라서 확인하려는 것은 키(인덱스)입니다. bash-4.0아니면 나중에 해야 합니다.

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

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

위에서 우리는 값에 대해 실제로 신경 쓰지 않으며 단지 null이 아니기만 하면 됩니다. 키와 값을 교환하여 인덱스 배열을 새로운 연관 배열로 "역전"할 수 있습니다.

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

답변2

가장 간단한 방법은 루프를 사용하여 반복하는 것입니다.

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

답변3

Bash 배열에 값이 포함되어 있는지 확인하는 방법


거짓 긍정 일치

array=(a1 b1 c1 d1 ee)

[[ ${array[*]} =~ 'a' ]] && echo 'yes' || echo 'no'
# output:
yes

[[ ${array[*]} =~ 'a1' ]] && echo 'yes' || echo 'no'
# output:
yes

[[ ${array[*]} =~ 'e' ]] && echo 'yes' || echo 'no'
# output:
yes

[[ ${array[*]} =~ 'ee' ]] && echo 'yes' || echo 'no'
# output:
yes

완전히 적합

정확히 일치하는 항목을 찾으려면 정규식 패턴에 값 앞뒤에 추가 공백이 있어야 합니다.(^|[[:space:]])"VALUE"($|[[:space:]])

# Exact match

array=(aa1 bc1 ac1 ed1 aee)

if [[ ${array[*]} =~ (^|[[:space:]])"a"($|[[:space:]]) ]]; then
    echo "Yes";
else
    echo "No";
fi
# output:
No

if [[ ${array[*]} =~ (^|[[:space:]])"ac1"($|[[:space:]]) ]]; then
    echo "Yes";
else
    echo "No";
fi
# output:
Yes

find="ac1"
if [[ ${array[*]} =~ (^|[[:space:]])"$find"($|[[:space:]]) ]]; then
    echo "Yes";
else
    echo "No";
fi
# output:
Yes

더 많은 사용 예시를 보려면 예시 소스를 확인하세요.여기

답변4

그리고 zsh:

array1=(
  prova1
  prova2
  slack64
)

a=slack64

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

배열 I첨자 플래그는 일치 항목의 가장 오른쪽 요소의 인덱스를 반환하는 데 사용됩니다 $a(또는 찾을 수 없는 경우 0). e이는 패턴 일치가 아니라 정확한/리터럴 일치입니다.


그리고 bash:

Bash의 배열 멤버는 NUL 바이트(zsh와 반대)를 포함할 수 없으므로 GNU 또는 호환 버전이 있는 경우 grep언제든지 다음을 수행할 수 있습니다.

if (( ${#array1[@]} )) && printf '%s\0' "${array1[@]}" | grep -zqxFe "$a"; then
  printf '%s\n' "$a in array1"
fi

즉, NUL로 구분된 요소를 인쇄하고 이러한 ero로 구분된 레코드 에 저장된 표현식과 일치하는 고정 문자열을 grep빠르게 찾도록 요청합니다.qxFe$az

관련 정보