1 #!/bin/bash
2 # query2.sh
3
4 numbers=(53 8 12 9 784 69 8 7 1)
5 i=4
6
7 echo ${numbers[@]} # <--- this echoes "53 8 12 9 784 69 8 7 1" to stdout.
8 echo ${numbers[i]} # <--- this echoes "784" to stdout.
9
10 unset numbers[i]
11
12 echo ${numbers[@]} # <--- this echoes "53 8 12 9 69 8 7 1" to stdout.
13 echo ${numbers[i]} # <--- stdout is blank.
배열이 12행의 stdout을 기반으로 업데이트된 것으로 보이는데 13행의 stdout이 비어 있는 이유는 무엇입니까?
그러면 예상되는 대답 "69"를 얻으려면 어떻게 해야 합니까?
답변1
unset
요소를 삭제합니다. 나머지 요소의 번호를 다시 매기지 않습니다.
우리는 이것을 사용하여 declare -p
무슨 일이 일어나고 있는지 확인할 수 있습니다 numbers
.
$ unset "numbers[i]"
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [5]="69" [6]="8" [7]="7" [8]="1")
관찰에는 numbers
더 이상 요소가 없습니다 4
.
다른 예시
관찰하다:
$ a=()
$ a[1]="element 1"
$ a[22]="element 22"
$ declare -p a
declare -a a=([1]="element 1" [22]="element 22")
배열에는 a
2부터 21까지의 요소가 없습니다. Bash에서는 배열 인덱스가 연속적일 필요가 없습니다.
인덱스 번호 다시 매기기에 권장되는 방법
numbers
누락된 요소가 있는 배열부터 시작해 보겠습니다 4
.
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [5]="69" [6]="8" [7]="7" [8]="1")
인덱스를 변경하려면 다음을 수행하십시오.
$ numbers=("${numbers[@]}")
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [4]="69" [5]="8" [6]="7" [7]="1")
이제 요소 번호가 있고 4
값이 있습니다 69
.
한 단계로 요소를 제거하고 배열 번호를 다시 매기는 또 다른 방법
다시 정의해 보겠습니다 numbers
.
$ numbers=(53 8 12 9 784 69 8 7 1)
제안대로토비 스페이트주석에는 다섯 번째 요소(인덱스 4)를 제거하고 한 단계로 나머지 요소의 번호를 다시 매기는 방법이 있습니다.
$ numbers=("${numbers[@]:0:4}" "${numbers[@]:5}")
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [4]="69" [5]="8" [6]="7" [7]="1")
보시다시피 다섯 번째 요소가 제거되고 나머지 모든 요소의 번호가 다시 매겨집니다.
${numbers[@]:0:4}
Slices array numbers
: 요소 0부터 시작하여 처음 4개의 요소를 가져옵니다.
마찬가지로 ${numbers[@]:5}
배열을 분할하면 numbers
요소 5부터 배열 끝까지 모든 요소를 가져옵니다.
배열의 인덱스 가져오기
이것가치${a[@]}
찾기 위해 배열을 얻는 데 사용할 수 있습니다 .색인(또는열쇠) 이 값에 해당하는 를 사용합니다 ${!a[@]}
.
예를 들어 배열에 numbers
요소가 누락되어 있다고 다시 생각해 보세요 4
.
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [5]="69" [6]="8" [7]="7" [8]="1")
어떤 인덱스가 할당되었는지 확인하려면 다음 안내를 따르세요.
$ echo "${!numbers[@]}"
0 1 2 3 5 6 7 8
이번에도 4
인덱스 목록에서 해당 값이 누락되었습니다.
문서
에서 man bash
:
내장
unset
함수는 배열을 파괴하는 데 사용됩니다.unset name[subscript]
index 에서 배열 요소를 삭제합니다subscript
. 인덱스 배열의 음수 첨자는 위와 같이 설명됩니다. 경로 이름 확장으로 인해 발생하는 원치 않는 부작용을 방지하려면 주의를 기울여야 합니다.unset name
,name
배열은 어디에 있습니까, 아니면unset name[subscript]
어디에subscript
있습니까?*
또는@
, 전체 배열을 삭제합니다.
답변2
bash
in과 같은 배열은 ksh
실제 배열이 아니라 연관 배열(또는 소위 말하는 배열)에 더 가깝습니다.희소 배열). 실제 배열이 있는 쉘의 경우 rc
, es
, fish
, , 와 같은 yash
쉘을 볼 수 있습니다 zsh
(비록 csh
/ tcsh
이러한 쉘에는 많은 문제가 있으므로 피하는 것이 가장 좋습니다).
존재하다 zsh
:
a=(1 2 3 4 5)
a[3]=() # remove the 3rd element
a[1,3]=() # remove the first 3 elements
a[-1]=() # remove the last element
(zsh에서는 unset 'a[3]'
와의 호환성을 향상시키기 위해 실제로 빈 문자열로 설정됩니다 ksh
.)
존재하다 yash
:
a=(1 2 3 4 5)
array -d a 3 # remove the 3rd element
array -d a 1 2 3 # remove the first 3 elements
array -d a -1 # remove the last element
( fish
/와 달리 Bourne과 같은 쉘이 아님):bash
zsh
set a 1 2 3 4 5
set -e a[3] # remove the 3rd element
set -e a[1..3] # remove the first 3 elements
set -e a[-1] # remove the last element
in es
( rc
Bourne과 같은 것이 아닌 를 기반으로 함)
a = 1 2 3 4 5
a = $a(... 2 4 ...) # remove the 3rd element
a = $a(4 ...) # remove the first 3 elements
a = $a(... `{expr $#a - 1}) # remove the last element
# or a convoluted way that avoids forking expr:
a = $a(... <={@{*=$*(2 ...); return $#*} $a})
ksh
함께 하다bash
이렇게 하면 해당 배열을 일반 배열로 사용할 수 있습니다.
a=("${a[@]}")
이로 인해 인덱스 목록이 연속되지 않거나 각 삭제 또는 삽입 작업 후에 0에서 시작되지 않을 수 있습니다. 또한 ksh
/ bash
배열은 1이 아닌 0에서 시작한다는 점에 유의하세요( $@
(어떤 면에서는 제외)).
이는 실제로 요소를 대조하고 순차적으로 인덱스 0, 1, 2...로 이동합니다.
또한 다음 사항을 인용해야 합니다 number[i]
.
unset 'number[i]'
그렇지 않으면 unset numberi
호출 중인 현재 디렉터리에 파일이 있으면 효과적으로 실행됩니다.numberi