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"
사용 grep
및 printf
:
(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}"* ]]
표기법이 계속해서 혼란 스럽기 때문에 일반적으로 grep
here-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
'development' 카테고리의 다른 글
프로젝트에있는 폴더에서 파일 읽기 (0) | 2020.12.03 |
---|---|
버튼을 점프시키는 부트 스트랩 툴팁 (0) | 2020.12.03 |
스크립팅을 사용하여 stdout을 파일과 콘솔 모두로 리디렉션하는 방법은 무엇입니까? (0) | 2020.12.03 |
문자열을 BigInteger로 어떻게 변환합니까? (0) | 2020.12.03 |
Swift 3 UnsafePointer ($ 0)는 더 이상 Xcode 8 베타 6에서 컴파일되지 않습니다. (0) | 2020.12.03 |