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


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.