배열 요소의 범위를 삭제하려고 하는데 실패합니다.
내 배열
root@ubuntu:~/work# echo ${a[@]}
cocacola.com airtel.com pepsi.com
0-1 배열 인쇄가 괜찮아 보입니다.
root@ubuntu:~/work# echo ${a[@]::2}
cocacola.com airtel.com
이제 다음을 사용하여 이러한 요소만 삭제하려고 합니다.
root@ubuntu:~/work# unset a[@]::2
root@ubuntu:~/work# echo ${a[@]}
전체 배열을 삭제하는 것입니다..
내가 뭘 잘못하고 있는 거지?
배열 범위를 삭제하는 다른 방법을 찾았지만 왜 위의 내용이 작동하지 않습니까?
for ((i=0; i<2; i++)); do unset a[$i]; done
편집 나도 시도했지만 운이 없었습니다
unset -v 'a[@]::2'
답변1
명심해야 할 한 가지는 bash
와 같은 배열 ksh
, 즉 키가 양의 정수로 제한되는 연관 배열로 구현된다는 것입니다( 예를 들어 perl
또는 같은 다른 언어와는 반대로 zsh
).
안에:
a[123]=foo a[456]=bar a[789]=baz
Bash에는 3개의 요소가 있는 연관 배열이 있고, Bash에는 perl
790개의 요소(zsh에서는 789)가 있는 배열이 있습니다.
ksh
or 에서는 키가 0보다 크거나 같은 키를 기준으로 숫자로 정렬된 요소 목록에서 배열의 첫 번째 요소를 반환합니다. 따라서 이 경우에는 bash
not 을 반환합니다 .${a[@]:0:1}
${a[123]}
${a[0]}
unset 'a[123]'
(인용하는 것을 기억하세요. 그렇지 않으면 현재 디렉토리에 a1, a2 또는 a3이라는 파일이 있으면 실패합니다.) 배열에서 특정 키를 제거하므로 의미가 있습니다.
unset 'a[@]::2'
그래도 말이되지 않습니다. , 또는 bash
만 이해하고 이후의 모든 내용은 무시되므로 동일한 작업을 수행합니다. 전체 배열을 설정 해제합니다 .unset a
unset 'a[123]'
unset 'a[*/@]'
unset 'a[@]::2'
unset 'a[@]please'
키 범위를 설정 해제하려면 키를 반복해야 합니다.
배열의 키 목록을 얻으려면 구문은 입니다 "${!a[@]}"
. 불행하게도 범위를 적용하는 것은 bash
nor 에서는 작동하지 않으므로 ksh
임시 배열이 필요합니다.
keys=("${!a[@]}")
for i in "${keys[@]::2}"; do unset "a[$i]"; done
이제 다른 언어와 마찬가지로 해당 배열을 고려하려면 unset
. 마찬가지로, 처음에 배열이 희박하지 않고 이를 유지하려는 경우(즉, 처음 두 요소를 설정 해제하는 대신 모든 요소를 2씩 이동하는 것) 다음과 같이 할 수 있습니다.
a=("${a[@]:2}")
이는 유지하려는 요소 목록으로 배열을 다시 할당하는 것입니다.
비교를 위해 zsh
.
a=({1..20})
unset 'a[12,16]'
요소 12~16에 빈 값을 설정합니다. 반면 unset 'a[16,20]'
배열을 15개 요소로 축소합니다.
a=({1..20})
a[12,16]=()
(여전히 zsh
)는 요소 17을 20으로 5자리만큼 이동하므로 를 a[12]
포함합니다 17
.
답변2
귀하의 배열이연속적/희소하지 않음(0..N-1 세트의 모든 요소)
다음을 사용하여 배열의 두 번째 요소를 제거할 수 있습니다.
unset 'a[1]'
두 번째, 세 번째, 네 번째 요소를 제거하려면 다음을 사용할 수 있습니다.
for ((i=1; i<=3; i++)); do unset "a[$i]"; done
첫 번째와 두 번째 요소를 제외한 모든 요소를 삭제하려면 다음을 사용할 수 있습니다.
for ((i=2; i<${#a[@]}; i++)); do unset "a[$i]"; done
일반 솔루션(희소 배열에도 작동): 다음을 사용하여 배열의 두 번째 요소를 제거할 수 있습니다.
unset "a[$(echo ${!a[@]} | cut -d" " -f 2)]"
두 번째, 세 번째, 네 번째 요소를 제거하려면 다음을 사용할 수 있습니다.
for $(echo ${!a[@]} | cut -d" " -f 2-4) ; do unset "a[$i]"; done
첫 번째와 두 번째 요소를 제외한 모든 요소를 삭제하려면 다음을 사용할 수 있습니다.
for $(echo ${!a[@]} | cut -d" " -f 2-) ; do unset "a[$i]"; done