development

Bash 배열에 요소가 있는지 확인

big-blog 2020. 12. 3. 08:07
반응형

Bash 배열에 요소가 있는지 확인


Bash의 배열 내에 요소가 있는지 확인하는 효율적인 방법이 있는지 궁금합니다. 다음과 같이 Python에서 할 수있는 것과 비슷한 것을 찾고 있습니다.

arr = ['a','b','c','d']

if 'd' in arr:
    do your thing
else:
    do something

Bash 4+의 bash에 대한 연관 배열을 사용하는 솔루션을 보았지만 다른 솔루션이 있는지 궁금합니다.

사소한 해결책이 배열을 반복하는 것이라는 것을 알고 있지만 그것을 원하지 않습니다.


다음과 같이 할 수 있습니다.

if [[ " ${arr[*]} " == *" d "* ]]; then
    echo "arr contains d"
fi

예를 들어 "a b"를 찾는 경우이 하위 문자열은 결합 된 문자열에 있지만 배열 요소는 아닙니다. 이 딜레마는 어떤 구분 기호를 선택하든 발생합니다.

가장 안전한 방법은 요소를 찾을 때까지 배열을 반복하는 것입니다.

array_contains () {
    local seeking=$1; shift
    local in=1
    for element; do
        if [[ $element == "$seeking" ]]; then
            in=0
            break
        fi
    done
    return $in
}

arr=(a b c "d e" f g)
array_contains "a b" "${arr[@]}" && echo yes || echo no    # no
array_contains "d e" "${arr[@]}" && echo yes || echo no    # yes

여기 모든 요소가 아닌 배열 이름 만 전달하는 "깨끗한"버전이 있습니다.

array_contains2 () { 
    local array="$1[@]"
    local seeking=$2
    local in=1
    for element in "${!array}"; do
        if [[ $element == "$seeking" ]]; then
            in=0
            break
        fi
    done
    return $in
}

array_contains2 arr "a b"  && echo yes || echo no    # no
array_contains2 arr "d e"  && echo yes || echo no    # yes

대한 연관 배열 배열이 주어진 포함되어있는 경우, 시험에 매우 깔끔한 방법이 키를 다음 -v연산자

$ declare -A arr=( [foo]=bar [baz]=qux )
$ [[ -v arr[foo] ]] && echo yes || echo no
yes
$ [[ -v arr[bar] ]] && echo yes || echo no
no

매뉴얼의 6.4 Bash 조건식을 참조하십시오 .


명백한주의 사항을 제쳐두고, 어레이가 실제로 위의 것과 같으면 다음을 수행 할 수 있습니다.

if [[ ${arr[*]} =~ d ]]
then
  do your thing
else
  do something
fi

1) 배열 초기화 arr및 요소 추가

2) 검색 할 변수 설정 SEARCH_STRING

3) 배열에 요소가 포함되어 있는지 확인

arr=()
arr+=('a')
arr+=('b')
arr+=('c')

SEARCH_STRING='b'

if [[ " ${arr[*]} " == *"$SEARCH_STRING"* ]];
then
    echo "YES, your arr contains $SEARCH_STRING"
else
    echo "NO, your arr does not contain $SEARCH_STRING"
fi

배열 요소에 공백이 포함되지 않은 경우 다른 (가독성이 더 높은) 솔루션은 다음과 같습니다.

if echo ${arr[@]} | grep -q -w "d"; then 
    echo "is in array"
else 
    echo "is not in array"
fi

반복하는 것보다 컴퓨팅 시간 측면에서 더 빠를 수있는 또 다른 방법이 있습니다. 확실하지 않다. 아이디어는 배열을 문자열로 변환하고 자르고 새 배열의 크기를 가져 오는 것입니다.

예를 들어 'd'의 색인을 찾으려면 다음을 수행하십시오.

arr=(a b c d)    
temp=`echo ${arr[@]}`
temp=( ${temp%%d*} )
index=${#temp[@]}

이것을 다음과 같은 함수로 바꿀 수 있습니다.

get-index() {

    Item=$1
    Array="$2[@]"

    ArgArray=( ${!Array} )
    NewArray=( ${!Array%%${Item}*} )

    Index=${#NewArray[@]}

    [[ ${#ArgArray[@]} == ${#NewArray[@]} ]] && echo -1 || echo $Index

}

그런 다음 다음을 호출 할 수 있습니다.

get-index d arr

다음과 같이 할당 할 수있는 3을 다시 에코합니다.

index=`get-index d arr`

array=("word" "two words") # let's look for "two words"

사용 grepprintf:

(printf '%s\n' "${array[@]}" | grep -x -q "two words") && <run_your_if_found_command_here>

사용 for:

(for e in "${array[@]}"; do [[ "$e" == "two words" ]] && exit 0; done; exit 1) && <run_your_if_found_command_here>

not_found 결과 추가 || <run_your_if_notfound_command_here>


bash에는 기본 제공 in 배열 연산자가없고 =~연산자 또는 [[ "${array[@]" == *"${item}"* ]]표기법이 계속해서 혼란 스럽기 때문에 일반적으로 grephere-string과 결합 합니다.

colors=('black' 'blue' 'light green')
if grep -q 'black' <<< "${colors[@]}"
then
    echo 'match'
fi

Beware however that this suffers from the same false positives issue as many of the other answers that occurs when the item to search for is fully contained, but is not equal to another item:

if grep -q 'green' <<< "${colors[@]}"
then
    echo 'should not match, but does'
fi

If that is an issue for your use case, you probably won't get around looping over the array:

for color in "${colors[@]}"
do
    if [ "${color}" = 'green' ]
    then
        echo "should not match and won't"
        break
    fi
done

for color in "${colors[@]}"
do
    if [ "${color}" = 'light green' ]
    then
        echo 'match'
        break
    fi
done

FWIW, here's what I used:

expr "${arr[*]}" : ".*\<$item\>"

This works where there are no delimiters in any of the array items or in the search target. I didn't need to solve the general case for my applicaiton.

참고URL : https://stackoverflow.com/questions/14366390/check-if-an-element-is-present-in-a-bash-array

반응형