선택한 요소의 색인을 표시하는 기능이 있습니다. 배열 이름으로 사용하기 위해 함수에 매개변수를 전달하려고 합니다. 이것은 작동합니다:
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을 추가하면 됩니다. 함수에 두 번째 인수를 추가하면 함수에 시작하거나 결과에 추가할 숫자를 알려주고 두 번째 인수가 누락된 경우 합리적인 기본값을 추가합니다. 또는 다음과 같이 인덱스를 반복합니다.스프라틱 씨제안.