답변:
Bash 4에서는 연관 배열을 사용할 수 있습니다.
# set up array of constants
declare -A array
for constant in foo bar baz
do
array[$constant]=1
done
# test for existence
test1="bar"
test2="xyzzy"
if [[ ${array[$test1]} ]]; then echo "Exists"; fi # Exists
if [[ ${array[$test2]} ]]; then echo "Exists"; fi # doesn't
처음에 어레이를 설정하려면 직접 할당을 수행 할 수도 있습니다.
array[foo]=1
array[bar]=1
# etc.
또는 이런 식으로 :
array=([foo]=1 [bar]=1 [baz]=1)
${array[$test1]}
간단하지만 문제가 있습니다. set -u
"언 바운드 변수"가 표시되므로 스크립트에서 사용하면 (권장) 작동하지 않습니다 .
오래된 질문이지만 가장 간단한 해결책은 아직 나타나지 않았다고 생각합니다 test ${array[key]+_}
. 예:
declare -A xs=([a]=1 [b]="")
test ${xs[a]+_} && echo "a is set"
test ${xs[b]+_} && echo "b is set"
test ${xs[c]+_} && echo "c is set"
출력 :
a is set
b is set
env
에서는 별명, 프로그 및 "test"라는 이름을 채택한 기타 기능의 모호성을 피하기 위해 사용할 것을 권장합니다. 위와 같이 env test ${xs[a]+_} && echo "a is set"
. 또한 이중 브래킷을 사용하여이 기능을 사용할 수 있으며, 다음과 같은 트릭으로 null을 검사합니다.[[ ! -z "${xs[b]+_}" ]] && echo "b is set"
[[ ${xs[b]+set} ]]
연관 배열의 요소가 존재하는지 (설정되지 않은) 테스트하는 방법이 있는데 이는 비어있는 것과 다릅니다.
isNotSet() {
if [[ ! ${!1} && ${!1-_} ]]
then
return 1
fi
}
그런 다음 사용하십시오.
declare -A assoc
KEY="key"
isNotSet assoc[${KEY}]
if [ $? -ne 0 ]
then
echo "${KEY} is not set."
fi
if ! some_check then return 1
=을 some_check
. 따라서 : isNotSet() { [[ ... ]] }
. 아래의 솔루션을 확인하십시오. 간단한 확인으로 해결할 수 있습니다.
어레이의 내용을 grep으로 파이프하여 항목이 있는지 확인할 수 있습니다.
printf "%s\n" "${mydata[@]}" | grep "^${val}$"
grep -n을 사용하여 항목의 색인을 가져올 수도 있습니다. 일치 항목의 행 번호를 반환합니다 (0부터 시작하는 색인을 얻으려면 1을 빼야 함). 매우 큰 배열을 제외하고는 상당히 빠릅니다.
# given the following data
mydata=(a b c "hello world")
for val in a c hello "hello world"
do
# get line # of 1st matching entry
ix=$( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 )
if [[ -z $ix ]]
then
echo $val missing
else
# subtract 1. Bash arrays are zero-based, but grep -n returns 1 for 1st line, not 0
echo $val found at $(( ix-1 ))
fi
done
a found at 0
c found at 2
hello missing
hello world found at 3
설명:
$( ... )
백틱을 사용하여 명령의 출력을 변수로 캡처하는 것과 동일 printf
mydata를 한 줄에 한 요소 씩 출력 @
대신에 필요한 모든 따옴표 *.
는 "hello world"를 2 줄로 나누지 않도록합니다)grep
정확한 문자열을 검색하고 줄의 시작과 끝 ^
과 $
일치grep -n
4 : hello world 형식으로 라인 #을 리턴합니다. grep -m 1
첫 번째 경기 만 찾습니다cut
줄 번호 만 추출 물론 빼기를 명령으로 접을 수 있습니다. 그러나 -1이 없는지 테스트하십시오.
ix=$(( $( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 ) - 1 ))
if [[ $ix == -1 ]]; then echo missing; else ... fi
$(( ... ))
정수 산술배열에 데이터 가 매우 제한되어 있지 않으면 반복하지 않고 제대로 수행 할 수 있다고 생각하지 않습니다 .
다음은 간단한 변형 "Super User"
입니다. 배열에 존재 한다고 올바르게 말합니다 . 그러나 그것은 또한"uper Use"
배열에 입니다.
MyArray=('Super User' 'Stack Overflow' 'Server Fault' 'Jeff' );
FINDME="Super User"
FOUND=`echo ${MyArray[*]} | grep "$FINDME"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
#
# If you where to add anchors < and > to the data it could work
# This would find "Super User" but not "uper Use"
#
MyArray2=('<Super User>' '<Stack Overflow>' '<Server Fault>' '<Jeff>' );
FOUND=`echo ${MyArray2[*]} | grep "<$FINDME>"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
문제는 배열을 반복하는 것 외에도 앵커를 쉽게 추가 할 수있는 방법이 없다는 것입니다. 배열에 넣기 전에 추가 할 수 없다면 ...
grep "\b$FINDME\b"
). 아마 비 영숫자와 공백이없는 상수와 함께 일할 수 "(^| )$FINDME(\$| )"
(나는 정규 표현식 그렙 사용 어떤 맛을 배울 수 없었습니다 ... 그런이나 뭐.)
#!/bin/bash
function in_array {
ARRAY=$2
for e in ${ARRAY[*]}
do
if [[ "$e" == "$1" ]]
then
return 0
fi
done
return 1
}
my_array=(Drupal Wordpress Joomla)
if in_array "Drupal" "${my_array[*]}"
then
echo "Found"
else
echo "Not found"
fi
in_array
. 건배
${ARRAY[@]}
되어야합니다.