질문에 대한 간략한 설명 :
이 내장되어 배시에있어서, 상기 어레이의 이름 (즉 변수에 저장) 동적 배시 배열의 요소 수를 계산하기 위해, 하지 A는 완전히 배열의 카피 제조 또는 사용에 의존 eval
?
추가 정보:
bash 매개 변수 대체를 사용하여 다음을 수행 할 수 있습니다.
- 배열의 길이를 결정하십시오
myArr=(A B C); echo ${#myArr[@]}
. - 이름으로 변수를 간접적으로 참조하십시오 :
NAME=myVar; echo ${!NAME}
(배열 요소에도 적용됩니다) :
NAME=myArr[1]; echo ${!NAME}
그러나 배열의 이름이 다른 변수에 저장되어 있으면 배열의 요소 수를 어떻게 결정할 수 있습니까? ( 이를 위의 두 매개 변수 대체 조합 으로 고려할 수 있습니다 .) 예를 들면 다음과 같습니다.
myArr=(A B C D)
NAME=myArr
# Get the number of elements in the array indirectly referenced by NAME.
count=${#$NAME[@]} # This syntax is invalid. What is the right way?
다음은 모두 실패한 여러 시도입니다.
# Setup for following attempts:
myArr=(A B C D)
NAME=myArr
EXPR1=$NAME[@] # i.e. EXPR1='myArr[@]'
EXPR2=#$NAME[@] # i.e. EXPR2='#myArr[@]'
# Failed attempts to get the lengh of the array indirectly:
1. count=${#$NAME[@]} # ERROR: bash: ...: bad substitution
2. count=${#!EXPR1} # ERROR: bash: !EXPR}: event not found
3. count=${#\!EXPR1} # ERROR: bash: ...: bad substitution
4. count=${!#EXPR1} # ERROR: bash: ...: bad substitution
5. count=${!EXPR2} # Returns NULL
또한 위의 다른 변형을 시도했지만 (A) 배열의 사본을 만들거나 (B)를 사용하여 작동하지 않는 것을 아직 찾지 못했습니다. eval
.
작업 방법 :
이 문제를 해결하는 두 가지 방법이 최적이 아닐 수도 있습니다 (그러나 내가 틀렸다면 정정하십시오).
방법 1 : 배열 복사
배열을 다른 (정적으로 명명 된) 변수에 할당하고 그 안의 요소 수를 가져옵니다.
EXPR=$NAME[@]
arrCopy=( "${!EXPR}" )
count=${#arrCopy}
방법 2 : 사용 eval
EXPR="count=\${#$NAME[@]}" # i.e. 'count=${myArr[@]}'
eval $EXPR
# Now count is set to the length of the array
요약:
bash에 배열의 길이를 간접적으로 결정하는 내장 메소드 (예 : 매개 변수 대체 구문)가 있습니까? 그렇지 않은 경우 가장 효율적인 방법은 무엇입니까? eval
위 의 방법 이라고 가정 하지만 보안 또는 성능 문제가 eval
있습니까?
time bash -c 'a=(1 a +); c=a; for ((i=0;i<100000;i++)); do eval "echo \${#$c[@]}"; done' > /dev/null
, 그리고 마찬가지로 e=$c[@]; d=("${!e}); echo ${#d[@]}
루프에서. 평가는 복사하는 데 걸리는 시간의 약 90 %가 걸렸습니다. 그리고 나는 간격이 배열과 그 요소가 더 커질 것이라고 생각합니다.