How can I remove an element from an array completely?

76,118

Solution 1

Just use array syntax on the assignment and quote your variable:

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

Edit according to question in comment. For $@ you can use it like this:

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

Solution 2

This had me thinking. The problem with sed/awk/tail is that they're line by line. After you delete the first line you have to write every other line from pattern space to the file.

  • You can use the following commands to do what you want in seconds.
  • This will write the entire file to an array.
  • Remove the first line as it dumps it back into the file.

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

Just change the largefile to the name of your file.

Share:
76,118

Related videos on Youtube

Ezequiel
Author by

Ezequiel

Updated on September 18, 2022

Comments

  • Ezequiel
    Ezequiel almost 2 years

    unset array[0] removes the element but still if I do echo ${array[0]} I get a null value moreover there are other ways of doing this but if an element of an array contains spaces like below

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

    but these also fail to do the job

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

    now I want the new array to be like

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

    The spaces cause the trouble after assignment and the actual array becomes like with substitution.

    array=(mary randy orton)
    
    • manatwork
      manatwork over 11 years
      No, not the spaces cause trouble, but the lack of quoting.
  • Stéphane Chazelas
    Stéphane Chazelas over 11 years
    Note that it doesn't remove the 1st element but the element of indice 0 and reassigns the indices. If the first element was on indice 12, it won't remove anything but will reassign the indices so that what once was on indice 12 will now be on indice 0. It's probably not a concern in the OP's case but should probably be noted for future reference. The behaviour is different with zsh whose arrays are not sparse contrary to ksh or bash.
  • Ezequiel
    Ezequiel over 11 years
    +1 i guess i am still wrong then if it does not remove the element.I was under the impression that array=("${array[@]:1}") removes the 1st element.
  • Steven Lu
    Steven Lu almost 11 years
    Hi @StephaneChazelas. The singular of "indices" is "index". Thanks for your comment!
  • user
    user over 10 years
    This would be much better if there was something to explain how it works and not just a blob of code. And what's with the tildes at the bottom?
  • William Everett
    William Everett almost 10 years
    If any element of q has spaces in it, this will break it up into multiple elements.
  • mike
    mike almost 8 years
    @manatwork How does it work on $@ (for functions and scripts)?
  • manatwork
    manatwork almost 8 years
    @Antoine, edited the answer.
  • don_crissti
    don_crissti almost 8 years
    @manatwork - re: your edit - why not using shift ?
  • manatwork
    manatwork almost 8 years
    @don_crissti, good point. I focused on the indexing difference and not thought further. Also had in mind the situation when you need to discard variable amount of items, for example to keep exactly the last 3: array=("${array[@]: -3}") and set -- "${@: -3}". So stuck at indices.
  • invot
    invot over 7 years
    Why not use sed -i 1d largefile instead? This even works for files bigger than RAM+swap
  • invot
    invot over 7 years
    shift $[$#-3] for the last 3 is probably much faster for $@
  • Kusalananda
    Kusalananda about 6 years
    shift will also remove the first element from $@.
  • anthony
    anthony about 4 years
    NO it does not replace element with a null, or empty string. it removes the element and creates a sparse array. That is an array with 'holes' in it. However looking up ANY undefined element in a sparse array returns a empty string! Sparse Arrays is perfectly valid for bash arrays! You can see it was removed using declare -p arr You can test if it is defined using [[ -v arr[1] ]] || echo not-defined