배열에서 인덱스 또는 키를 확인하는 가장 쉬운 방법은 무엇입니까?
사용:
set -o nounset
다음과 같은 인덱스 배열을 사용하는 경우:
myArray=( "red" "black" "blue" )
요소 1이 설정되어 있는지 확인하는 가장 빠른 방법은 무엇입니까?
나는 가끔 다음을 사용합니다.test "${#myArray[@]}" -gt "1" && echo "1 exists" || echo "1 doesn't exist"
저는 선호하는 것이 있는지 알고 싶습니다.
비연속 인덱스를 처리하는 방법은 무엇입니까?
myArray=() myArray[12]="red" myArray[51]="black" myArray[129]="blue"
▁▁that를 빠르게 하는 방법.
51
예를 들어 이미 설정되었습니까?연관 배열을 처리하는 방법은 무엇입니까?
declare -A myArray myArray["key1"]="red" myArray["key2"]="black" myArray["key3"]="blue"
▁▁that를 빠르게 하는 방법.
key2
예를 들어 이미 사용되었습니까?
요소가 설정되었는지 확인합니다(인덱스 배열과 연관 배열 모두에 적용됨).
[ "${array[key]+abc}" ] && echo "exists"
기본적으로 무엇입니까?${array[key]+abc}
is .
- 한다면
array[key]
set, 설됨정, 반환을 반환합니다.abc
- 한다면
array[key]
도 반환하지 않습니다. 아무것도 반환하지 않습니다.
References:
콜론이 생략되면 연산자는 [파라미터의] 존재만 테스트합니다.
- 이 답변은 실제로 이 SO 질문에 대한 답변에서 채택되었습니다.문자열이 bash 셸 스크립트에 정의되어 있지 않은지 확인하는 방법은 무엇입니까?
래퍼 함수:
exists(){
if [ "$2" != in ]; then
echo "Incorrect usage."
echo "Correct usage: exists {key} in {array}"
return
fi
eval '[ ${'$3'[$1]+muahaha} ]'
}
예를들면
if ! exists key in array; then echo "No such array element"; fi
맨배시에서 조건식:
-v varname
True if the shell variable varname is set (has been assigned a value).
예:
declare -A foo
foo[bar]="this is bar"
foo[baz]=""
if [[ -v "foo[bar]" ]] ; then
echo "foo[bar] is set"
fi
if [[ -v "foo[baz]" ]] ; then
echo "foo[baz] is set"
fi
if [[ -v "foo[quux]" ]] ; then
echo "foo[quux] is set"
fi
그러면 foo[bar]와 foo[baz]가 모두 설정되어 있고(후자가 빈 값으로 설정되어 있더라도) foo[quux]가 설정되어 있지 않은 것으로 나타납니다.
새로운 답변
bash(및 최신 버전) 4.2부터는 기본 제공 명령에 대한 새로운 옵션이 제공됩니다.
버전 4.3부터 이 테스트는 어레이 요소를 다룰 수 있습니다.
array=([12]="red" [51]="black" [129]="blue")
for i in 10 12 30 {50..52} {128..131};do
if [ -v 'array[i]' ];then
echo "Variable 'array[$i]' is defined"
else
echo "Variable 'array[$i]' not exist"
fi
done
Variable 'array[10]' not exist
Variable 'array[12]' is defined
Variable 'array[30]' not exist
Variable 'array[50]' not exist
Variable 'array[51]' is defined
Variable 'array[52]' not exist
Variable 'array[128]' not exist
Variable 'array[129]' is defined
Variable 'array[130]' not exist
Variable 'array[131]' not exist
참고: SSC의 코멘트와 관련하여, 저는 단일 인용을 했습니다.'array[i]'
-v
테스트, 셸체크의 오류를 만족시키기 위해SC2208. 여기에는 글로벌 캐릭터가 없기 때문에 이것이 실제로 필요하지 않은 것 같습니다.array[i]
어쨌든...
이 기능은 다음과 같은 방식으로 연결 어레이에서 작동합니다.
declare -A aArray=([foo]="bar" [bar]="baz" [baz]=$'Hello world\041')
for i in alpha bar baz dummy foo test;do
if [ -v 'aArray[$i]' ];then
echo "Variable 'aArray[$i]' is defined"
else
echo "Variable 'aArray[$i]' not exist"
fi
done
Variable 'aArray[alpha]' not exist
Variable 'aArray[bar]' is defined
Variable 'aArray[baz]' is defined
Variable 'aArray[dummy]' not exist
Variable 'aArray[foo]' is defined
Variable 'aArray[test]' not exist
약간의 차이로:
배열에서(일반배열는서사변수의이괄호에▁between변(▁in수▁variable일▁brackets▁(의,이▁regular▁arrays[i]
기호는 다음과 같습니다.$
)가 필요하지 않지만 연상 배열의 경우 키가 단어이기 때문에$
항목입니다.[$i]
)!
V4.2 이전 버전의 bash에 대한 이전 응답
안타깝게도 bash는 빈 변수와 정의되지 않은 변수를 구분할 수 있는 방법을 제공하지 않습니다.
하지만 몇 가지 방법이 있습니다.
$ array=()
$ array[12]="red"
$ array[51]="black"
$ array[129]="blue"
$ echo ${array[@]}
red black blue
$ echo ${!array[@]}
12 51 129
$ echo "${#array[@]}"
3
$ printf "%s\n" ${!array[@]}|grep -q ^51$ && echo 51 exist
51 exist
$ printf "%s\n" ${!array[@]}|grep -q ^52$ && echo 52 exist
(무응답)
연관 배열의 경우에도 동일하게 사용할 수 있습니다.
$ unset array
$ declare -A array
$ array["key1"]="red"
$ array["key2"]="black"
$ array["key3"]="blue"
$ echo ${array[@]}
blue black red
$ echo ${!array[@]}
key3 key2 key1
$ echo ${#array[@]}
3
$ set | grep ^array=
array=([key3]="blue" [key2]="black" [key1]="red" )
$ printf "%s\n" ${!array[@]}|grep -q ^key2$ && echo key2 exist || echo key2 not exist
key2 exist
$ printf "%s\n" ${!array[@]}|grep -q ^key5$ && echo key5 exist || echo key5 not exist
key5 not exist
외부 도구 없이도 작업을 수행할 수 있으며(순수 bash로 printf|grep 없음), 새 bash 함수로 build checkIfExist():
$ checkIfExist() {
eval 'local keys=${!'$1'[@]}';
eval "case '$2' in
${keys// /|}) return 0 ;;
* ) return 1 ;;
esac";
}
$ checkIfExist array key2 && echo exist || echo don\'t
exist
$ checkIfExist array key5 && echo exist || echo don\'t
don't
또는 원하는 값이 존재하지 않으면 false result-code로 종료하고 원하는 값을 반환하는 새로운 getIfExist bash 함수를 만들기도 합니다.
$ getIfExist() {
eval 'local keys=${!'$1'[@]}';
eval "case '$2' in
${keys// /|}) echo \${$1[$2]};return 0 ;;
* ) return 1 ;;
esac";
}
$ getIfExist array key1
red
$ echo $?
0
$ # now with an empty defined value
$ array["key4"]=""
$ getIfExist array key4
$ echo $?
0
$ getIfExist array key5
$ echo $?
1
A는 어떻습니까?-n
and the 스트및테:-
교환원?
예를 들어, 이 스크립트는 다음과 같습니다.
#!/usr/bin/env bash
set -e
set -u
declare -A sample
sample["ABC"]=2
sample["DEF"]=3
if [[ -n "${sample['ABC']:-}" ]]; then
echo "ABC is set"
fi
if [[ -n "${sample['DEF']:-}" ]]; then
echo "DEF is set"
fi
if [[ -n "${sample['GHI']:-}" ]]; then
echo "GHI is set"
fi
인쇄:
ABC is set
DEF is set
bash 4.3.39 (1)-release에서 테스트됨
declare -A fmap
fmap['foo']="boo"
key='foo'
# should echo foo is set to 'boo'
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi
key='blah'
# should echo blah is unset in fmap
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi
Thamme에서 이것을 반복합니다.
[[ ${array[key]+Y} ]] && echo Y || echo N
이는 변수/어레이 요소가 null 값으로 설정되어 있는지 여부를 포함하여 변수/어레이 요소가 있는지 여부를 테스트합니다.이것은 -v보다 더 넓은 범위의 bash 버전에서 작동하며 set -u와 같은 것에 민감하지 않은 것으로 보입니다.이 방법을 사용하는 "불량 배열 첨자"가 표시되면 예제를 게시하십시오.
이것이 제가 찾은 가장 쉬운 스크립트 방법입니다.
<search>
찾으려는 문자열, 연관 배열을 포함하는 변수의 이름입니다.
달성하고자 하는 목표에 따라 달라집니다.
키 존재:
if grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key is present; fi
키가 없습니다.
if ! grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key not present; fi
값이 존재합니다.
if grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value is present; fi
값이 존재하지 않습니다.
if ! grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value not present; fi
Bash의 배열에 키가 있는지 확인하는 기능을 작성했습니다.
# Check if array key exists
# Usage: array_key_exists $array_name $key
# Returns: 0 = key exists, 1 = key does NOT exist
function array_key_exists() {
local _array_name="$1"
local _key="$2"
local _cmd='echo ${!'$_array_name'[@]}'
local _array_keys=($(eval $_cmd))
local _key_exists=$(echo " ${_array_keys[@]} " | grep " $_key " &>/dev/null; echo $?)
[[ "$_key_exists" = "0" ]] && return 0 || return 1
}
예
declare -A my_array
my_array['foo']="bar"
if [[ "$(array_key_exists 'my_array' 'foo'; echo $?)" = "0" ]]; then
echo "OK"
else
echo "ERROR"
fi
GNU bash 버전 4.1.5 (1)-release(i486-pc-linux-gnu)로 테스트됨
영원히 사람들을 위해, 영원히.
"깨끗한 코드"가 있고, 더 짧고 간결한 배쉬 중심의 방법이 있습니다.
$1
찾고 있는 인덱스 또는 키입니다.
$2
배열/지도가 참조로 전달되었습니다.
function hasKey ()
{
local -r needle="${1:?}"
local -nr haystack=${2:?}
for key in "${!haystack[@]}"; do
if [[ $key == $needle ]] ;
return 0
fi
done
return 1
}
선형 검색은 큰 데이터 세트에서 더 나은 성능을 발휘하는 이진 검색으로 대체될 수 있습니다.먼저 키를 세고 정렬한 다음 정답에 가까워질수록 건초 더미의 고전적인 이진법을 절반으로 나눕니다.
이제 "아니요, bash에서 대규모 어레이를 처리해야 할 수도 있기 때문에 더 성능이 뛰어난 버전을 원합니다."와 같은 순수한 사용자를 위해 bash 중심의 솔루션을 살펴보겠습니다. 그러나 깨끗한 코드와 어레이 또는 맵을 처리할 수 있는 유연성을 유지하는 솔루션을 살펴보겠습니다.
function hasKey ()
{
local -r needle="${1:?}"
local -nr haystack=${2:?}
[ -n ${haystack["$needle"]+found} ]
}
인[ -n ${haystack["$needle"]+found} ]
를 사용합니다.${parameter+word}
bash가 확장 입니다.${parameter:+word}
키의 값을 테스트하려고 시도하는 양식입니다. 이는 당면한 문제가 아닙니다.
사용.
local -A person=(firstname Anthony lastname Rutledge)
if hasMapKey "firstname" person; then
# Do something
fi
하위 문자열 확장을 수행하지 않는 경우 아래에 설명된 형식(예: ':-')을 사용하여 Bash가 설정되지 않았거나 null인 매개 변수를 테스트합니다.콜론을 생략하면 설정되지 않은 파라미터에 대해서만 테스트가 수행됩니다.즉, 콜론이 포함된 경우 연산자는 매개 변수의 존재 여부와 값이 모두 null이 아닌지를 테스트합니다. 콜론이 생략된 경우 연산자는 존재 여부만 테스트합니다.
${parameter:-word}
If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
${parameter:=word}
If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional
매개 변수 및 특수 매개 변수는 이러한 방식으로 할당할 수 없습니다.${매개 변수:?word}
If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard
오류가 발생하면 셸이 종료됩니다.그렇지 않으면 매개 변수 값이 대체됩니다.${매개 변수:+word}
If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.
https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion
한다면$needle
0에서 0으로 확장하지 않고 0이 아닌 길이 문자열 "found"로 확장합니다.이것은 다음을 만들 것입니다.-n
테스트는 성공적입니다.$needle
실제로 존재하며("찾았다"고 말함) 그렇지 않으면 실패합니다.
어레이와 해시 맵 모두에서 가장 쉽고 간단한 솔루션은 일치하는 연산자를 사용하는 것입니다.=~
.
어레이의 경우:
myArray=("red" "black" "blue")
if [[ " ${myArray[@]} " =~ " blue " ]]; then
echo "blue exists in myArray"
else
echo "blue does not exist in myArray"
fi
참고: 배열 주위의 공백은 첫 번째 요소와 마지막 요소가 일치하도록 보장합니다.값 주위의 공백은 정확한 일치를 보장합니다.
해시 맵의 경우 해시 맵을 문자열로 인쇄하면 값 목록이 제공되므로 실제로 동일한 솔루션입니다.
declare -A myMap
myMap=(
["key1"]="red"
["key2"]="black"
["key3"]="blue"
)
if [[ " ${myMap[@]} " =~ " blue " ]]; then
echo "blue exists in myMap"
else
echo "blue does not exist in myMap"
fi
하지만 해시 맵에 키가 있는지 확인하고 싶다면 어떻게 하시겠습니까?사용할 수 있는 경우!
해시 맵의 키 목록을 제공하는 연산자입니다.
if [[ " ${!myMap[@]} " =~ " key3 " ]]; then
echo "key3 exists in myMap"
else
echo "key3 does not exist in myMap"
fi
알겠습니다bad array subscript
제가 확인하는 키가 설정되지 않았을 때의 오류입니다.그래서 저는 키 위에 루프하는 기능을 만들었습니다.
#!/usr/bin/env bash
declare -A helpList
function get_help(){
target="$1"
for key in "${!helpList[@]}";do
if [[ "$key" == "$target" ]];then
echo "${helpList["$target"]}"
return;
fi
done
}
targetValue="$(get_help command_name)"
if [[ -z "$targetvalue" ]];then
echo "command_name is not set"
fi
이 값은 찾을 때는 값을 에코하고 찾을 때는 아무 것도 에코하지 않습니다.제가 시도한 다른 모든 해결책들은 저에게 그 오류를 주었습니다.
언급URL : https://stackoverflow.com/questions/13219634/easiest-way-to-check-for-an-index-or-a-key-in-an-array
'programing' 카테고리의 다른 글
이클립스:저장 시 코드를 포맷할 수 있습니까? (0) | 2023.05.11 |
---|---|
하위 모듈이 아닌 경로에 대한 하위 모듈 매핑을 .git 모듈에서 찾을 수 없습니다. (0) | 2023.05.06 |
GitHub 저장소의 내용 복제(폴더 자체 없음) (0) | 2023.05.06 |
모노가 황금 시간대에 준비되었습니까? (0) | 2023.05.06 |
장고 모델에서 열거형을 선택 필드로 사용하려면 어떻게 해야 합니까? (0) | 2023.05.06 |