배열에서 요소를 완전히 제거하려면 어떻게해야합니까?


48

unset array[0]요소를 제거하지만 여전히 echo ${array[0]}null 값을 얻는 경우이 작업 을 수행하는 다른 방법이 있지만 배열의 요소에 아래와 같은 공백이 있으면

array[0]='james young'
array[1]='mary'
array[2]='randy orton'

그러나 이것들은 또한 일을하지 못한다

array=${array[@]:1} #removed the 1st element

이제 새로운 배열을 원합니다

array[0]='mary'
array[1]='randy orton'

공백은 할당 후 문제를 일으키고 실제 배열은 대체와 같습니다.

array=(mary randy orton)

4
아니요, 공백은 문제를 일으키지 않지만 인용 부호가 없습니다.
manatwork

답변:


68

할당에 배열 구문을 사용하고 변수를 인용하십시오.

array=("${array[@]:1}") #removed the 1st element

의견의 질문에 따라 편집하십시오 . 들어 $@당신은 다음과 같이 사용할 수 있습니다 :

set -- "${@:2}" #removed the 1st parameter

8
첫 번째 요소가 아니라 indice 0 요소를 제거 하고 인덱스를 다시 할당합니다. 첫 번째 요소가 12 번 인도어에 있었으면 아무것도 제거하지 않고 인덱스를 재 할당하여 12 번 단계에 있던 것이 이제 0 번 인도에있게됩니다. 아마도 OP의 경우에는 문제가되지 않지만 아마도 향후 참조. zshksh 또는 bash와 반대로 배열이 희소하지 않은 동작은 다릅니다 .
Stéphane Chazelas

3
@StephaneChazelas 님 안녕하세요. "indices"의 단수는 " index "입니다. 귀하의 의견에 감사드립니다!
Steven Lu

3
@ manatwork-re : 편집-왜 사용하지 shift않습니까?
don_crissti

1
@don_crissti, 좋은 지적입니다. 나는 색인 차이에 초점을 맞추었고 더 이상 생각하지 않았습니다. 또한 예를 들어 마지막 3 array=("${array[@]: -3}")과를 정확하게 유지하기 위해 가변 량의 항목을 버려야하는 상황도 염두에 두었습니다 set -- "${@: -3}". 지수에 갇혀있었습니다.
manatwork

1
shift $[$#-3]$@
Tino

0

이것은 나를 생각하게했다. sed / awk / tail의 문제점은 라인 단위라는 것입니다. 첫 번째 행을 삭제 한 후에는 패턴 공간에서 파일로 다른 모든 행을 작성해야합니다.

  • 다음 명령을 사용하여 몇 초 안에 원하는 것을 수행 할 수 있습니다.
  • 전체 파일을 배열에 씁니다.
  • 파일로 다시 덤프 할 때 첫 번째 행을 제거하십시오.

    readarray -t aLargeFile < <(cat largefile)
    echo "${aLargeFile[@]:1}" >largefile
    

largefile파일 이름으로 변경 하십시오.


sed -i 1d largefile대신 사용 하지 않습니까? 이것은 심지어 RAM + 스왑보다 큰 파일에서도 작동합니다
Tino

0

특정 인덱스에서 요소를 제거하기 unset위해 다른 배열로 복사 한 다음 사용할 수 있습니다 . unset이 경우 에만 필요하지 않습니다. unset요소를 제거하지 않기 때문에 null 문자열을 배열의 특정 색인으로 설정합니다.

declare -a arr=('aa' 'bb' 'cc' 'dd' 'ee')
unset 'arr[1]'
declare -a arr2=()
i=0
for element in ${arr[@]}
do
    arr2[$i]=$element
    ((++i))
done
echo ${arr[@]}
echo "1st val is ${arr[1]}, 2nd val is ${arr[2]}"
echo ${arr2[@]}
echo "1st val is ${arr2[1]}, 2nd val is ${arr2[2]}"

출력

aa cc dd ee
1st val is , 2nd val is cc
aa cc dd ee
1st val is cc, 2nd val is dd

-1
#!/bin/bash

q=( one two three four five )

echo -e "
  (remove) { [:range:] } <- [:list:]
                | [:range:] => return list with range removed range is in the form of [:digit:]-[:digit:]
"

function remove {
  if [[ $1 =~ ([[:digit:]])(-([[:digit:]]))?   ]]; then
    from=${BASH_REMATCH[1]}
    to=${BASH_REMATCH[3]}
  else
    echo bad range
  fi;shift
  array=( ${@} )
  local start=${array[@]::${from}}
  local rest
  [ -n "$to" ] && rest=${array[@]:((${to}+1))}  || rest=${array[@]:((${from}+1))}
  echo ${start[@]} ${rest[@]}
}

q=( `remove 1 ${q[*]}` )
echo ${q[@]}
~                                                                                                                                                              
~                       

4
이것은 단지 코드 덩어리가 아니라 작동 방식을 설명 할 무언가가 있다면 훨씬 좋습니다. 그리고 바닥의 물결표는 무엇입니까?
CVn

3
진심으로, 당신은 맞습니다. 이것은 훌리건이 쓴 것처럼 보이지만 감사합니다. 나는 햄버거 서빙 일 사이에 이것을 정말로 몰래 가져옵니다.
MageProspero

q의 요소에 공백이 있으면 여러 요소로 나뉩니다.
윌리엄 에버렛
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.