선택한 요소의 색인을 표시하는 기능이 있습니다. 배열 이름으로 사용하기 위해 함수에 매개변수를 전달하려고 합니다. 이것은 작동합니다:
getIndex() {
arrname=$1[@]
b=("${!arrname}")
index=1; while ((index<${#b[@]})); do
if [[ "${b[$index]}" = "$VALUE" ]]; then
echo "index is $index"; return
fi
((index++)); done
}
하지만 이 함수에 이름을 전달한 배열에는 첫 번째 요소의 인덱스로 인덱스 1이 있습니다(줄 번호와 유사한 인덱스를 가지려면 이 인덱스가 필요하며, 이 인덱스에서 배열의 패턴을 얻습니다.
a=1
while read line; do
if [[ $line =~ ^[0-9] ]]; then
avg[$a]=`echo $line | awk '{print $6}'`
((a++));
fi
그리고 getIndex() 함수를 실행하면 배열의 첫 번째 요소는 인덱스 0에서 시작됩니다.
따라서 질문은 다음과 같습니다. 배열의 인덱스를 저장하는 기능을 수행하기 위해 매개변수에 배열 이름을 전달할 수 있는 방법이 있습니까? 아니면 그냥 잊어버리고 함수 응답에 +1을 추가해야 할 수도 있습니다.
답변1
다음 구성을 사용하고 있습니다.
b=("${!arrname}")
이는가치배열의 다음을 b[]
사용 하여 새 배열을 만듭니다.bash 기본 배열 인덱스는 0부터 시작합니다.. 배열의 복사본을 적절하게 초기화하려면 인덱스를 복원해야 합니다(예: eval
출력을 구문 분석하거나 -ing하여 declare -p arrname
).
복사하는 것보다 더 나은 접근 방식은인덱스값 대신 이를 사용하여 배열을 반복합니다. 이 접근 방식은 희박하거나 0이 아닌 기반의 표준 배열(및 bash4 연관 배열)에서도 작동합니다.
문제점(항상 존재하는 것은 아님)은 !
이중 의무를 수행한다는 것입니다. 간접 참조에서의 사용은 ${!name}
배열 인덱스 확장에 대한 사용과 호환되지 않으므로 ${!arrname[@]}
을 사용해야 합니다 eval
.
이를 구현하는 수정된 버전은 다음과 같습니다.
getIndex2() {
local arrname=$1 iidx idxs index ival val
printf -v iidx '"${!%s[@]}"' "$arrname"
eval "idxs=($iidx)"
for index in "${idxs[@]}"; do
printf -v ival '${%s[%s]}' "$arrname" "$index"
eval "val=$ival"
if [[ "${val}" = "$VALUE" ]]; then
echo "index is $index"; return
fi
done
}
printf -v var ...
읽기 가능한 상태를 유지하려면 (bash-3.1+) 을 사용하세요 eval
. 인덱스는 배열로 확장됩니다. 이는 꼭 필요한 것은 아니며 단순 목록도 가능합니다.
또한보십시오배쉬FAQ/006.
답변2
Bash의 배열은 0부터 시작합니다. 그들은 단지 그렇습니다. 즉, 만약 당신이알다 배열이 항상 1부터 시작하는 숫자로 인덱싱되도록 하려면 결과에 +1을 추가하면 됩니다. 함수에 두 번째 인수를 추가하면 시작하거나 결과에 추가할 숫자를 알려주고 두 번째 인수가 누락된 경우에 적합한 기본값을 추가합니다. 또는 다음과 같이 인덱스를 반복합니다.미스터 스퓨라틱제안.