Remove an element from a Bash arrayRemove element from bash array by content (stored in variable) without leaving a blank slotbash: Remove variable from array?Remove value from array bashHow do you unset all empty array elements in bash?Remove multiple elements from array based on indexHow can I compile all .cpp files except one using g++?Bash, remove a value from an array (by value) (in a function)Get the source directory of a Bash script from within the script itselfCreate ArrayList from arrayHow to append something to an array?Deleting an element from an array in PHPHow to check if a program exists from a Bash script?How do I tell if a regular file does not exist in Bash?How to concatenate string variables in BashHow do I remove a particular element from an array in JavaScript?Loop through an array of strings in Bash?For-each over an array in JavaScript?

Using Python in a Bash Script

Exploiting the delay when a festival ticket is scanned

Should I put my name first, or last in the team members list

What would the United Kingdom's "optimal" Brexit deal look like?

What are the closest international airports in different countries?

Can you continue the movement of a Bonus Action Dash granted by Expeditious Retreat if your Concentration is broken mid-move?

How can flights operated by the same company have such different prices when marketed by another?

How would a lunar colony attack Earth?

Spider-Man and Fantastic 4 crossover comic with Double Identity Scene

Why does calling cout.operator<<(const char*) print the address instead of the character string?

On the sensitivity conjecture?

Avoiding Implicit Conversion in Constructor. Explicit keyword doesn't help here

How to innovate in OR

Why are prop blades not shaped like household fan blades?

Reading electrical clamp tester higher voltage/amp 400A

How to prevent a single-element caster from being useless against immune foes?

Can a US President, after impeachment and removal, be re-elected or re-appointed?

How should I quote American English speakers in a British English essay?

Move arrows along a contour

Why would anyone ever invest in a cash-only etf?

How to foreshadow to avoid a 'deus ex machina'-construction

What is a good example for artistic ND filter applications?

Efficiently finding furthest two nodes in a graph

Unknown indication below upper stave



Remove an element from a Bash array


Remove element from bash array by content (stored in variable) without leaving a blank slotbash: Remove variable from array?Remove value from array bashHow do you unset all empty array elements in bash?Remove multiple elements from array based on indexHow can I compile all .cpp files except one using g++?Bash, remove a value from an array (by value) (in a function)Get the source directory of a Bash script from within the script itselfCreate ArrayList from arrayHow to append something to an array?Deleting an element from an array in PHPHow to check if a program exists from a Bash script?How do I tell if a regular file does not exist in Bash?How to concatenate string variables in BashHow do I remove a particular element from an array in JavaScript?Loop through an array of strings in Bash?For-each over an array in JavaScript?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








79















I need to remove an element from an array in bash shell.
Generally I'd simply do:



array=("$(@)array:#<element to remove>")


Unfortunately the element I want to remove is a variable so I can't use the previous command.
Down here an example:



array+=(pluto)
array+=(pippo)
delete=(pluto)
array( $array[@]/$delete ) -> but clearly doesn't work because of


Any idea?










share|improve this question


























  • Which shell? Your example looks like zsh.

    – chepner
    May 31 '13 at 16:30











  • array=( $array[@]/$delete ) works as expected in Bash. Have you simply missed the =?

    – Ken Sharp
    Jan 17 '18 at 19:56











  • @Ken, that's not quite what's wanted - it will remove any matches from each string, and leave empty strings in the array where it matches the whole string.

    – Toby Speight
    Feb 27 at 15:05

















79















I need to remove an element from an array in bash shell.
Generally I'd simply do:



array=("$(@)array:#<element to remove>")


Unfortunately the element I want to remove is a variable so I can't use the previous command.
Down here an example:



array+=(pluto)
array+=(pippo)
delete=(pluto)
array( $array[@]/$delete ) -> but clearly doesn't work because of


Any idea?










share|improve this question


























  • Which shell? Your example looks like zsh.

    – chepner
    May 31 '13 at 16:30











  • array=( $array[@]/$delete ) works as expected in Bash. Have you simply missed the =?

    – Ken Sharp
    Jan 17 '18 at 19:56











  • @Ken, that's not quite what's wanted - it will remove any matches from each string, and leave empty strings in the array where it matches the whole string.

    – Toby Speight
    Feb 27 at 15:05













79












79








79


20






I need to remove an element from an array in bash shell.
Generally I'd simply do:



array=("$(@)array:#<element to remove>")


Unfortunately the element I want to remove is a variable so I can't use the previous command.
Down here an example:



array+=(pluto)
array+=(pippo)
delete=(pluto)
array( $array[@]/$delete ) -> but clearly doesn't work because of


Any idea?










share|improve this question
















I need to remove an element from an array in bash shell.
Generally I'd simply do:



array=("$(@)array:#<element to remove>")


Unfortunately the element I want to remove is a variable so I can't use the previous command.
Down here an example:



array+=(pluto)
array+=(pippo)
delete=(pluto)
array( $array[@]/$delete ) -> but clearly doesn't work because of


Any idea?







arrays bash variables






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 15 '18 at 1:16









codeforester

20.1k8 gold badges44 silver badges75 bronze badges




20.1k8 gold badges44 silver badges75 bronze badges










asked May 31 '13 at 15:31









AlexAlex

4121 gold badge4 silver badges6 bronze badges




4121 gold badge4 silver badges6 bronze badges















  • Which shell? Your example looks like zsh.

    – chepner
    May 31 '13 at 16:30











  • array=( $array[@]/$delete ) works as expected in Bash. Have you simply missed the =?

    – Ken Sharp
    Jan 17 '18 at 19:56











  • @Ken, that's not quite what's wanted - it will remove any matches from each string, and leave empty strings in the array where it matches the whole string.

    – Toby Speight
    Feb 27 at 15:05

















  • Which shell? Your example looks like zsh.

    – chepner
    May 31 '13 at 16:30











  • array=( $array[@]/$delete ) works as expected in Bash. Have you simply missed the =?

    – Ken Sharp
    Jan 17 '18 at 19:56











  • @Ken, that's not quite what's wanted - it will remove any matches from each string, and leave empty strings in the array where it matches the whole string.

    – Toby Speight
    Feb 27 at 15:05
















Which shell? Your example looks like zsh.

– chepner
May 31 '13 at 16:30





Which shell? Your example looks like zsh.

– chepner
May 31 '13 at 16:30













array=( $array[@]/$delete ) works as expected in Bash. Have you simply missed the =?

– Ken Sharp
Jan 17 '18 at 19:56





array=( $array[@]/$delete ) works as expected in Bash. Have you simply missed the =?

– Ken Sharp
Jan 17 '18 at 19:56













@Ken, that's not quite what's wanted - it will remove any matches from each string, and leave empty strings in the array where it matches the whole string.

– Toby Speight
Feb 27 at 15:05





@Ken, that's not quite what's wanted - it will remove any matches from each string, and leave empty strings in the array where it matches the whole string.

– Toby Speight
Feb 27 at 15:05












18 Answers
18






active

oldest

votes


















124














The following works as you would like in bash and zsh:



$ array=(pluto pippo)
$ delete=(pluto)
$ echo $array[@]/$delete
pippo
$ array=( "$array[@]/$delete" ) #Quotes when working with strings


If need to delete more than one element:



...
$ delete=(pluto pippo)
for del in $delete[@]
do
array=("$array[@]/$del") #Quotes when working with strings
done


Caveat



This technique actually removes prefixes matching $delete from the elements, not necessarily whole elements.



Update



To really remove an exact item, you need to walk through the array, comparing the target to each element, and using unset to delete an exact match.



array=(pluto pippo bob)
delete=(pippo)
for target in "$delete[@]"; do
for i in "$!array[@]"; do
if [[ $array[i] = "$delete[0]" ]]; then
unset 'array[i]'
fi
done
done


Note that if you do this, and one or more elements is removed, the indices will no longer be a continuous sequence of integers.



$ declare -p array
declare -a array=([0]="pluto" [2]="bob")


The simple fact is, arrays were not designed for use as mutable data structures. They are primarily used for storing lists of items in a single variable without needing to waste a character as a delimiter (e.g., to store a list of strings which can contain whitespace).



If gaps are a problem, then you need to rebuild the array to fill the gaps:



for i in "$!array[@]"; do
new_array+=( "$array[i]" )
done
array=("$new_array[@]")
unset new_array





share|improve this answer






















  • 31





    just know that: $ array=(sun sunflower) $ delete=(sun) $ echo $array[@]/$delete results in flower

    – bernstein
    Mar 26 '14 at 14:41







  • 9





    Note that this is actually doing a substitution, so if the array is something like (pluto1 pluto2 pippo) then you will end up with (1 2 pippo).

    – haridsv
    Sep 22 '14 at 5:22







  • 2





    Just be careful using this in a for loop because you'll end up with an empty element where the deleted element was. For sanity you could do something like for element in "$array[@]" do if [[ $element ]]; then echo $element fi done

    – Joel B
    Oct 21 '15 at 23:29







  • 2





    So how to delete only matching elements?

    – UmaN
    Feb 19 '16 at 9:09






  • 3





    Note: this may set the respective value to nothing, but the element will still be in the array.

    – Blauhirn
    Mar 26 '16 at 12:01


















23














You could build up a new array without the undesired element, then assign it back to the old array. This works in bash:



array=(pluto pippo)
new_array=()
for value in "$array[@]"
do
[[ $value != pluto ]] && new_array+=($value)
done
array=("$new_array[@]")
unset new_array


This yields:



echo "$array[@]"
pippo





share|improve this answer
































    7














    This is the most direct way to unset a value if you know it's position.



    $ array=(one two three)
    $ echo $#array[@]
    3
    $ unset 'array[1]'
    $ echo $array[@]
    one three
    $ echo $#array[@]
    2





    share|improve this answer




















    • 3





      Try echo $array[1], you will get null string. And to get three you need to do echo $array[2]. So unset is not the right mechanism to remove an element in bash array.

      – rashok
      Apr 3 '18 at 9:23


















    4














    Here's a one-line solution with mapfile:



    $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "<regexp>")


    Example:



    $ arr=("Adam" "Bob" "Claire"$'n'"Smith" "David" "Eve" "Fred")

    $ echo "Size: $#arr[*] Contents: $arr[*]"

    Size: 6 Contents: Adam Bob Claire
    Smith David Eve Fred

    $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "^ClairenSmith$")

    $ echo "Size: $#arr[*] Contents: $arr[*]"

    Size: 5 Contents: Adam Bob David Eve Fred


    This method allows for great flexibility by modifying/exchanging the grep command and doesn't leave any empty strings in the array.






    share|improve this answer






















    • 1





      Please use printf '%sn' "$array[@]" instead of that ugly IFS/echo thing.

      – gniourf_gniourf
      Jan 15 '17 at 19:07












    • Note that this fails with fields that contain newlines.

      – gniourf_gniourf
      Jan 15 '17 at 19:08











    • I've edited the answer to allow newlines in fields.

      – Niklas Holm
      Mar 23 '18 at 8:14











    • @Socowi You're incorrect, at least on bash 4.4.19. -d $'' works perfectly fine while just -d without the argument does not.

      – Niklas Holm
      Mar 27 at 9:13











    • Ah yes, I mixed it up. Sorry. What I meant was: -d $'' is the same as-d $' something' or just -d ''.

      – Socowi
      Mar 27 at 9:27



















    2














    To expand on the above answers, the following can be used to remove multiple elements from an array, without partial matching:



    ARRAY=(one two onetwo three four threefour "one six")
    TO_REMOVE=(one four)

    TEMP_ARRAY=()
    for pkg in "$ARRAY[@]"; do
    for remove in "$TO_REMOVE[@]"; do
    KEEP=true
    if [[ $pkg == $remove ]]; then
    KEEP=false
    break
    fi
    done
    if $KEEP; then
    TEMP_ARRAY+=($pkg)
    fi
    done
    ARRAY=("$TEMP_ARRAY[@]")
    unset TEMP_ARRAY


    This will result in an array containing:
    (two onetwo three threefour "one six")






    share|improve this answer
































      2














      Here's a (probably very bash-specific) little function involving bash variable indirection and unset; it's a general solution that does not involve text substitution or discarding empty elements and has no problems with quoting/whitespace etc.



      delete_ary_elmt() 
      local word=$1 # the element to search for & delete
      local aryref="$2[@]" # a necessary step since '$!$2[@]' is a syntax error
      local arycopy=("$!aryref") # create a copy of the input array
      local status=1
      for (( i = $#arycopy[@] - 1; i >= 0; i-- )); do # iterate over indices backwards
      elmt=$arycopy[$i]
      [[ $elmt == $word ]] && unset "$2[$i]" && status=0 # unset matching elmts in orig. ary
      done
      return $status # return 0 if something was deleted; 1 if not


      array=(a 0 0 b 0 0 0 c 0 d e 0 0 0)
      delete_ary_elmt 0 array
      for e in "$array[@]"; do
      echo "$e"
      done

      # prints "a" "b" "c" "d" in lines


      Use it like delete_ary_elmt ELEMENT ARRAYNAME without any $ sigil. Switch the == $word for == $word* for prefix matches; use $elmt,, == $word,, for case-insensitive matches; etc., whatever bash [[ supports.



      It works by determining the indices of the input array and iterating over them backwards (so deleting elements doesn't screw up iteration order). To get the indices you need to access the input array by name, which can be done via bash variable indirection x=1; varname=x; echo $!varname # prints "1".



      You can't access arrays by name like aryname=a; echo "$$aryname[@], this gives you an error. You can't do aryname=a; echo "$!aryname[@]", this gives you the indices of the variable aryname (although it is not an array). What DOES work is aryref="a[@]"; echo "$!aryref", which will print the elements of the array a, preserving shell-word quoting and whitespace exactly like echo "$a[@]". But this only works for printing the elements of an array, not for printing its length or indices (aryref="!a[@]" or aryref="#a[@]" or "$!!aryref" or "$#!aryref", they all fail).



      So I copy the original array by its name via bash indirection and get the indices from the copy. To iterate over the indices in reverse I use a C-style for loop. I could also do it by accessing the indices via $!arycopy[@] and reversing them with tac, which is a cat that turns around the input line order.



      A function solution without variable indirection would probably have to involve eval, which may or may not be safe to use in that situation (I can't tell).






      share|improve this answer

























      • This almost works nicely, however it doesn't redeclare the initial array passed into the function, so while that initial array has its values missing, it also has its indexes messed up. What this mean is that the next call you make to delete_ary_elmt on the same array will not work (or will remove the wrong things). For instance, after what you have pasted, try running delete_ary_elmt "d" array and then re-printing the array. You will see that the wrong element gets removed. Removing the last element will also then never work.

        – Scott
        Feb 26 '18 at 19:26


















      1














      Using unset



      To remove an element at particular index, we can use unset and then do copy to another array. Only just unset is not required in this case. Because unset does not remove the element it just sets null string to the particular index in array.



      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]"


      Output is



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


      Using :<idx>



      We can remove some set of elements using :<idx> also. For example if we want to remove 1st element we can use :1 as mentioned below.



      declare -a arr=('aa' 'bb' 'cc' 'dd' 'ee')
      arr2=("$arr[@]:1")
      echo "$arr2[@]"
      echo "1st val is $arr2[1], 2nd val is $arr2[2]"


      Output is



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





      share|improve this answer


































        0














        POSIX shell script does not have arrays.



        So most probably you are using a specific dialect such as bash, korn shells or zsh.



        Therefore, your question as of now cannot be answered.



        Maybe this works for you:



        unset array[$delete]





        share|improve this answer




















        • 2





          Hi, I'm using bash shell atm. And "$delete" is not the position of the element but the string itself. So I don't think "unset" will work

          – Alex
          May 31 '13 at 16:07



















        0














        Actually, I just noticed that the shell syntax somewhat has a behavior built-in that allows for easy reconstruction of the array when, as posed in the question, an item should be removed.



        # let's set up an array of items to consume:
        x=()
        for (( i=0; i<10; i++ )); do
        x+=("$i")
        done

        # here, we consume that array:
        while (( $#x[@] )); do
        i=$(( $RANDOM % $#x[@] ))
        echo "$x[i] / $x[@]"
        x=("$x[@]:0:i" "$x[@]:i+1")
        done


        Notice how we constructed the array using bash's x+=() syntax?



        You could actually add more than one item with that, the content of a whole other array at once.






        share|improve this answer


































          0














          http://wiki.bash-hackers.org/syntax/pe#substring_removal




          $PARAMETER#PATTERN # remove from beginning



          $PARAMETER##PATTERN # remove from the beginning, greedy match



          $PARAMETER%PATTERN # remove from the end



          $PARAMETER%%PATTERN # remove from the end, greedy match




          In order to do a full remove element, you have to do an unset command with an if statement. If you don't care about removing prefixes from other variables or about supporting whitespace in the array, then you can just drop the quotes and forget about for loops.



          See example below for a few different ways to clean up an array.



          options=("foo" "bar" "foo" "foobar" "foo bar" "bars" "bar")

          # remove bar from the start of each element
          options=("$options[@]/#"bar"")
          # options=("foo" "" "foo" "foobar" "foo bar" "s" "")

          # remove the complete string "foo" in a for loop
          count=$#options[@]
          for ((i = 0; i < count; i++)); do
          if [ "$options[i]" = "foo" ] ; then
          unset 'options[i]'
          fi
          done
          # options=( "" "foobar" "foo bar" "s" "")

          # remove empty options
          # note the count variable can't be recalculated easily on a sparse array
          for ((i = 0; i < count; i++)); do
          # echo "Element $i: '$options[i]'"
          if [ -z "$options[i]" ] ; then
          unset 'options[i]'
          fi
          done
          # options=("foobar" "foo bar" "s")

          # list them with select
          echo "Choose an option:"
          PS3='Option? '
          select i in "$options[@]" Quit
          do
          case $i in
          Quit) break ;;
          *) echo "You selected "$i"" ;;
          esac
          done


          Output



          Choose an option:
          1) foobar
          2) foo bar
          3) s
          4) Quit
          Option?


          Hope that helps.






          share|improve this answer


































            0














            In ZSH this is dead easy (note this uses more bash compatible syntax than necessary where possible for ease of understanding):



            # I always include an edge case to make sure each element
            # is not being word split.
            start=(one two three 'four 4' five)
            work=($(@)start)

            idx=2
            val=$work[idx]

            # How to remove a single element easily.
            # Also works for associative arrays (at least in zsh)
            work[$idx]=()

            echo "Array size went down by one: "
            [[ $#work -eq $(($#start - 1)) ]] && echo "OK"

            echo "Array item "$val" is now gone: "
            [[ -z $work[(r)$val] ]] && echo OK

            echo "Array contents are as expected: "
            wanted=("$start[@]:0:1" "$start[@]:2")
            [[ "$(j.:.)wanted[@]" == "$(j.:.)work[@]" ]] && echo "OK"

            echo "-- array contents: start --"
            print -l -r -- "-- $#start elements" $(@)start
            echo "-- array contents: work --"
            print -l -r -- "-- $#work elements" "$work[@]"


            Results:



            Array size went down by one:
            OK
            Array item two is now gone:
            OK
            Array contents are as expected:
            OK
            -- array contents: start --
            -- 5 elements
            one
            two
            three
            four 4
            five
            -- array contents: work --
            -- 4 elements
            one
            three
            four 4
            five





            share|improve this answer



























            • Sorry, just tried. It did not work in zsh for an assoziative array

              – Falk
              Dec 8 '18 at 22:43












            • It works just fine, I just tested it (again). Things not working for you? Please explain what did not work exactly in as much detail as you can. What ZSH version are you using?

              – trevorj
              Apr 2 at 2:51



















            0














            There is also this syntax, e.g. if you want to delete the 2nd element :



            array=("$array[@]:0:1" "$array[@]:2")


            which is in fact the concatenation of 2 tabs. The first from the index 0 to the index 1 (exclusive) and the 2nd from the index 2 to the end.






            share|improve this answer


































              0














              Partial answer only



              To delete the first item in the array



              unset 'array[0]'


              To delete the last item in the array



              unset 'array[-1]'





              share|improve this answer


































                0














                To avoid conflicts with array index using unset - see https://stackoverflow.com/a/49626928/3223785 and https://stackoverflow.com/a/47798640/3223785 for more information - reassign the array to itself: ARRAY_VAR=($ARRAY_VAR[@]).



                #!/bin/bash

                ARRAY_VAR=(0 1 2 3 4 5 6 7 8 9)
                unset ARRAY_VAR[5]
                unset ARRAY_VAR[4]
                ARRAY_VAR=($ARRAY_VAR[@])
                echo $ARRAY_VAR[@]
                A_LENGTH=$#ARRAY_VAR[*]
                for (( i=0; i<=$(( $A_LENGTH -1 )); i++ )) ; do
                echo ""
                echo "INDEX - $i"
                echo "VALUE - $ARRAY_VAR[$i]"
                done

                exit 0


                [Ref.: https://tecadmin.net/working-with-array-bash-script/ ]






                share|improve this answer
































                  -1














                  What I do is:



                  array="$(echo $array | tr ' ' 'n' | sed "/itemtodelete/d")"


                  BAM, that item is removed.






                  share|improve this answer






















                  • 1





                    This breaks for array=('first item' 'second item').

                    – Benjamin W.
                    Jun 14 '16 at 17:17


















                  -1














                  This is a quick-and-dirty solution that will work in simple cases but will break if (a) there are regex special characters in $delete, or (b) there are any spaces at all in any items. Starting with:



                  array+=(pluto)
                  array+=(pippo)
                  delete=(pluto)


                  Delete all entries exactly matching $delete:



                  array=(`echo $array | fmt -1 | grep -v "^$delete$" | fmt -999999`)


                  resulting in
                  echo $array -> pippo, and making sure it's an array:
                  echo $array[1] -> pippo



                  fmt is a little obscure: fmt -1 wraps at the first column (to put each item on its own line. That's where the problem arises with items in spaces.) fmt -999999 unwraps it back to one line, putting back the spaces between items. There are other ways to do that, such as xargs.



                  Addendum: If you want to delete just the first match, use sed, as described here:



                  array=(`echo $array | fmt -1 | sed "0,/^$delete$///d;" | fmt -999999`)





                  share|improve this answer


































                    -1














                    How about something like:



                    array=(one two three)
                    array_t=" $array[@] "
                    delete=one
                    array=($array_t// $delete / )
                    unset array_t





                    share|improve this answer
































                      -2














                      #/bin/bash

                      echo "# define array with six elements"
                      arr=(zero one two three 'four 4' five)

                      echo "# unset by index: 0"
                      unset -v 'arr[0]'
                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                      arr_delete_by_content() # value to delete
                      for i in $!arr[*]; do
                      [ "$arr[$i]" = "$1" ] && unset -v 'arr[$i]'
                      done


                      echo "# unset in global variable where value: three"
                      arr_delete_by_content three
                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                      echo "# rearrange indices"
                      arr=( "$arr[@]" )
                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                      delete_value() sed 's,^[^=]*=,,'


                      echo "# new array without value: two"
                      declare -a arr="$(delete_value two "$arr[@]")"
                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                      delete_values() # arraydecl values..., returns array decl. (keeps indices)
                      declare -a arr="$1"; local i v; shift
                      for v in "$@"; do
                      for i in $!arr[*]; do
                      [ "$v" = "$arr[$i]" ] && unset -v 'arr[$i]'
                      done
                      done
                      declare -p arr
                      echo "# new array without values: one five (keep indices)"
                      declare -a arr="$(delete_values "$(declare -p arr|sed 's,^[^=]*=,,')" one five)"
                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                      # new array without multiple values and rearranged indices is left to the reader





                      share|improve this answer




















                      • 1





                        Can you add some comments or a description to tell us about your answer?

                        – Michael
                        Oct 17 '17 at 19:26











                      protected by codeforester Sep 15 '18 at 1:16



                      Thank you for your interest in this question.
                      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                      Would you like to answer one of these unanswered questions instead?














                      18 Answers
                      18






                      active

                      oldest

                      votes








                      18 Answers
                      18






                      active

                      oldest

                      votes









                      active

                      oldest

                      votes






                      active

                      oldest

                      votes









                      124














                      The following works as you would like in bash and zsh:



                      $ array=(pluto pippo)
                      $ delete=(pluto)
                      $ echo $array[@]/$delete
                      pippo
                      $ array=( "$array[@]/$delete" ) #Quotes when working with strings


                      If need to delete more than one element:



                      ...
                      $ delete=(pluto pippo)
                      for del in $delete[@]
                      do
                      array=("$array[@]/$del") #Quotes when working with strings
                      done


                      Caveat



                      This technique actually removes prefixes matching $delete from the elements, not necessarily whole elements.



                      Update



                      To really remove an exact item, you need to walk through the array, comparing the target to each element, and using unset to delete an exact match.



                      array=(pluto pippo bob)
                      delete=(pippo)
                      for target in "$delete[@]"; do
                      for i in "$!array[@]"; do
                      if [[ $array[i] = "$delete[0]" ]]; then
                      unset 'array[i]'
                      fi
                      done
                      done


                      Note that if you do this, and one or more elements is removed, the indices will no longer be a continuous sequence of integers.



                      $ declare -p array
                      declare -a array=([0]="pluto" [2]="bob")


                      The simple fact is, arrays were not designed for use as mutable data structures. They are primarily used for storing lists of items in a single variable without needing to waste a character as a delimiter (e.g., to store a list of strings which can contain whitespace).



                      If gaps are a problem, then you need to rebuild the array to fill the gaps:



                      for i in "$!array[@]"; do
                      new_array+=( "$array[i]" )
                      done
                      array=("$new_array[@]")
                      unset new_array





                      share|improve this answer






















                      • 31





                        just know that: $ array=(sun sunflower) $ delete=(sun) $ echo $array[@]/$delete results in flower

                        – bernstein
                        Mar 26 '14 at 14:41







                      • 9





                        Note that this is actually doing a substitution, so if the array is something like (pluto1 pluto2 pippo) then you will end up with (1 2 pippo).

                        – haridsv
                        Sep 22 '14 at 5:22







                      • 2





                        Just be careful using this in a for loop because you'll end up with an empty element where the deleted element was. For sanity you could do something like for element in "$array[@]" do if [[ $element ]]; then echo $element fi done

                        – Joel B
                        Oct 21 '15 at 23:29







                      • 2





                        So how to delete only matching elements?

                        – UmaN
                        Feb 19 '16 at 9:09






                      • 3





                        Note: this may set the respective value to nothing, but the element will still be in the array.

                        – Blauhirn
                        Mar 26 '16 at 12:01















                      124














                      The following works as you would like in bash and zsh:



                      $ array=(pluto pippo)
                      $ delete=(pluto)
                      $ echo $array[@]/$delete
                      pippo
                      $ array=( "$array[@]/$delete" ) #Quotes when working with strings


                      If need to delete more than one element:



                      ...
                      $ delete=(pluto pippo)
                      for del in $delete[@]
                      do
                      array=("$array[@]/$del") #Quotes when working with strings
                      done


                      Caveat



                      This technique actually removes prefixes matching $delete from the elements, not necessarily whole elements.



                      Update



                      To really remove an exact item, you need to walk through the array, comparing the target to each element, and using unset to delete an exact match.



                      array=(pluto pippo bob)
                      delete=(pippo)
                      for target in "$delete[@]"; do
                      for i in "$!array[@]"; do
                      if [[ $array[i] = "$delete[0]" ]]; then
                      unset 'array[i]'
                      fi
                      done
                      done


                      Note that if you do this, and one or more elements is removed, the indices will no longer be a continuous sequence of integers.



                      $ declare -p array
                      declare -a array=([0]="pluto" [2]="bob")


                      The simple fact is, arrays were not designed for use as mutable data structures. They are primarily used for storing lists of items in a single variable without needing to waste a character as a delimiter (e.g., to store a list of strings which can contain whitespace).



                      If gaps are a problem, then you need to rebuild the array to fill the gaps:



                      for i in "$!array[@]"; do
                      new_array+=( "$array[i]" )
                      done
                      array=("$new_array[@]")
                      unset new_array





                      share|improve this answer






















                      • 31





                        just know that: $ array=(sun sunflower) $ delete=(sun) $ echo $array[@]/$delete results in flower

                        – bernstein
                        Mar 26 '14 at 14:41







                      • 9





                        Note that this is actually doing a substitution, so if the array is something like (pluto1 pluto2 pippo) then you will end up with (1 2 pippo).

                        – haridsv
                        Sep 22 '14 at 5:22







                      • 2





                        Just be careful using this in a for loop because you'll end up with an empty element where the deleted element was. For sanity you could do something like for element in "$array[@]" do if [[ $element ]]; then echo $element fi done

                        – Joel B
                        Oct 21 '15 at 23:29







                      • 2





                        So how to delete only matching elements?

                        – UmaN
                        Feb 19 '16 at 9:09






                      • 3





                        Note: this may set the respective value to nothing, but the element will still be in the array.

                        – Blauhirn
                        Mar 26 '16 at 12:01













                      124












                      124








                      124







                      The following works as you would like in bash and zsh:



                      $ array=(pluto pippo)
                      $ delete=(pluto)
                      $ echo $array[@]/$delete
                      pippo
                      $ array=( "$array[@]/$delete" ) #Quotes when working with strings


                      If need to delete more than one element:



                      ...
                      $ delete=(pluto pippo)
                      for del in $delete[@]
                      do
                      array=("$array[@]/$del") #Quotes when working with strings
                      done


                      Caveat



                      This technique actually removes prefixes matching $delete from the elements, not necessarily whole elements.



                      Update



                      To really remove an exact item, you need to walk through the array, comparing the target to each element, and using unset to delete an exact match.



                      array=(pluto pippo bob)
                      delete=(pippo)
                      for target in "$delete[@]"; do
                      for i in "$!array[@]"; do
                      if [[ $array[i] = "$delete[0]" ]]; then
                      unset 'array[i]'
                      fi
                      done
                      done


                      Note that if you do this, and one or more elements is removed, the indices will no longer be a continuous sequence of integers.



                      $ declare -p array
                      declare -a array=([0]="pluto" [2]="bob")


                      The simple fact is, arrays were not designed for use as mutable data structures. They are primarily used for storing lists of items in a single variable without needing to waste a character as a delimiter (e.g., to store a list of strings which can contain whitespace).



                      If gaps are a problem, then you need to rebuild the array to fill the gaps:



                      for i in "$!array[@]"; do
                      new_array+=( "$array[i]" )
                      done
                      array=("$new_array[@]")
                      unset new_array





                      share|improve this answer















                      The following works as you would like in bash and zsh:



                      $ array=(pluto pippo)
                      $ delete=(pluto)
                      $ echo $array[@]/$delete
                      pippo
                      $ array=( "$array[@]/$delete" ) #Quotes when working with strings


                      If need to delete more than one element:



                      ...
                      $ delete=(pluto pippo)
                      for del in $delete[@]
                      do
                      array=("$array[@]/$del") #Quotes when working with strings
                      done


                      Caveat



                      This technique actually removes prefixes matching $delete from the elements, not necessarily whole elements.



                      Update



                      To really remove an exact item, you need to walk through the array, comparing the target to each element, and using unset to delete an exact match.



                      array=(pluto pippo bob)
                      delete=(pippo)
                      for target in "$delete[@]"; do
                      for i in "$!array[@]"; do
                      if [[ $array[i] = "$delete[0]" ]]; then
                      unset 'array[i]'
                      fi
                      done
                      done


                      Note that if you do this, and one or more elements is removed, the indices will no longer be a continuous sequence of integers.



                      $ declare -p array
                      declare -a array=([0]="pluto" [2]="bob")


                      The simple fact is, arrays were not designed for use as mutable data structures. They are primarily used for storing lists of items in a single variable without needing to waste a character as a delimiter (e.g., to store a list of strings which can contain whitespace).



                      If gaps are a problem, then you need to rebuild the array to fill the gaps:



                      for i in "$!array[@]"; do
                      new_array+=( "$array[i]" )
                      done
                      array=("$new_array[@]")
                      unset new_array






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Dec 13 '17 at 10:39









                      muru

                      3,45718 silver badges56 bronze badges




                      3,45718 silver badges56 bronze badges










                      answered May 31 '13 at 16:33









                      chepnerchepner

                      280k40 gold badges275 silver badges370 bronze badges




                      280k40 gold badges275 silver badges370 bronze badges










                      • 31





                        just know that: $ array=(sun sunflower) $ delete=(sun) $ echo $array[@]/$delete results in flower

                        – bernstein
                        Mar 26 '14 at 14:41







                      • 9





                        Note that this is actually doing a substitution, so if the array is something like (pluto1 pluto2 pippo) then you will end up with (1 2 pippo).

                        – haridsv
                        Sep 22 '14 at 5:22







                      • 2





                        Just be careful using this in a for loop because you'll end up with an empty element where the deleted element was. For sanity you could do something like for element in "$array[@]" do if [[ $element ]]; then echo $element fi done

                        – Joel B
                        Oct 21 '15 at 23:29







                      • 2





                        So how to delete only matching elements?

                        – UmaN
                        Feb 19 '16 at 9:09






                      • 3





                        Note: this may set the respective value to nothing, but the element will still be in the array.

                        – Blauhirn
                        Mar 26 '16 at 12:01












                      • 31





                        just know that: $ array=(sun sunflower) $ delete=(sun) $ echo $array[@]/$delete results in flower

                        – bernstein
                        Mar 26 '14 at 14:41







                      • 9





                        Note that this is actually doing a substitution, so if the array is something like (pluto1 pluto2 pippo) then you will end up with (1 2 pippo).

                        – haridsv
                        Sep 22 '14 at 5:22







                      • 2





                        Just be careful using this in a for loop because you'll end up with an empty element where the deleted element was. For sanity you could do something like for element in "$array[@]" do if [[ $element ]]; then echo $element fi done

                        – Joel B
                        Oct 21 '15 at 23:29







                      • 2





                        So how to delete only matching elements?

                        – UmaN
                        Feb 19 '16 at 9:09






                      • 3





                        Note: this may set the respective value to nothing, but the element will still be in the array.

                        – Blauhirn
                        Mar 26 '16 at 12:01







                      31




                      31





                      just know that: $ array=(sun sunflower) $ delete=(sun) $ echo $array[@]/$delete results in flower

                      – bernstein
                      Mar 26 '14 at 14:41






                      just know that: $ array=(sun sunflower) $ delete=(sun) $ echo $array[@]/$delete results in flower

                      – bernstein
                      Mar 26 '14 at 14:41





                      9




                      9





                      Note that this is actually doing a substitution, so if the array is something like (pluto1 pluto2 pippo) then you will end up with (1 2 pippo).

                      – haridsv
                      Sep 22 '14 at 5:22






                      Note that this is actually doing a substitution, so if the array is something like (pluto1 pluto2 pippo) then you will end up with (1 2 pippo).

                      – haridsv
                      Sep 22 '14 at 5:22





                      2




                      2





                      Just be careful using this in a for loop because you'll end up with an empty element where the deleted element was. For sanity you could do something like for element in "$array[@]" do if [[ $element ]]; then echo $element fi done

                      – Joel B
                      Oct 21 '15 at 23:29






                      Just be careful using this in a for loop because you'll end up with an empty element where the deleted element was. For sanity you could do something like for element in "$array[@]" do if [[ $element ]]; then echo $element fi done

                      – Joel B
                      Oct 21 '15 at 23:29





                      2




                      2





                      So how to delete only matching elements?

                      – UmaN
                      Feb 19 '16 at 9:09





                      So how to delete only matching elements?

                      – UmaN
                      Feb 19 '16 at 9:09




                      3




                      3





                      Note: this may set the respective value to nothing, but the element will still be in the array.

                      – Blauhirn
                      Mar 26 '16 at 12:01





                      Note: this may set the respective value to nothing, but the element will still be in the array.

                      – Blauhirn
                      Mar 26 '16 at 12:01













                      23














                      You could build up a new array without the undesired element, then assign it back to the old array. This works in bash:



                      array=(pluto pippo)
                      new_array=()
                      for value in "$array[@]"
                      do
                      [[ $value != pluto ]] && new_array+=($value)
                      done
                      array=("$new_array[@]")
                      unset new_array


                      This yields:



                      echo "$array[@]"
                      pippo





                      share|improve this answer





























                        23














                        You could build up a new array without the undesired element, then assign it back to the old array. This works in bash:



                        array=(pluto pippo)
                        new_array=()
                        for value in "$array[@]"
                        do
                        [[ $value != pluto ]] && new_array+=($value)
                        done
                        array=("$new_array[@]")
                        unset new_array


                        This yields:



                        echo "$array[@]"
                        pippo





                        share|improve this answer



























                          23












                          23








                          23







                          You could build up a new array without the undesired element, then assign it back to the old array. This works in bash:



                          array=(pluto pippo)
                          new_array=()
                          for value in "$array[@]"
                          do
                          [[ $value != pluto ]] && new_array+=($value)
                          done
                          array=("$new_array[@]")
                          unset new_array


                          This yields:



                          echo "$array[@]"
                          pippo





                          share|improve this answer













                          You could build up a new array without the undesired element, then assign it back to the old array. This works in bash:



                          array=(pluto pippo)
                          new_array=()
                          for value in "$array[@]"
                          do
                          [[ $value != pluto ]] && new_array+=($value)
                          done
                          array=("$new_array[@]")
                          unset new_array


                          This yields:



                          echo "$array[@]"
                          pippo






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Jun 29 '15 at 18:21









                          Steve KehletSteve Kehlet

                          4,3823 gold badges26 silver badges34 bronze badges




                          4,3823 gold badges26 silver badges34 bronze badges
























                              7














                              This is the most direct way to unset a value if you know it's position.



                              $ array=(one two three)
                              $ echo $#array[@]
                              3
                              $ unset 'array[1]'
                              $ echo $array[@]
                              one three
                              $ echo $#array[@]
                              2





                              share|improve this answer




















                              • 3





                                Try echo $array[1], you will get null string. And to get three you need to do echo $array[2]. So unset is not the right mechanism to remove an element in bash array.

                                – rashok
                                Apr 3 '18 at 9:23















                              7














                              This is the most direct way to unset a value if you know it's position.



                              $ array=(one two three)
                              $ echo $#array[@]
                              3
                              $ unset 'array[1]'
                              $ echo $array[@]
                              one three
                              $ echo $#array[@]
                              2





                              share|improve this answer




















                              • 3





                                Try echo $array[1], you will get null string. And to get three you need to do echo $array[2]. So unset is not the right mechanism to remove an element in bash array.

                                – rashok
                                Apr 3 '18 at 9:23













                              7












                              7








                              7







                              This is the most direct way to unset a value if you know it's position.



                              $ array=(one two three)
                              $ echo $#array[@]
                              3
                              $ unset 'array[1]'
                              $ echo $array[@]
                              one three
                              $ echo $#array[@]
                              2





                              share|improve this answer













                              This is the most direct way to unset a value if you know it's position.



                              $ array=(one two three)
                              $ echo $#array[@]
                              3
                              $ unset 'array[1]'
                              $ echo $array[@]
                              one three
                              $ echo $#array[@]
                              2






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Dec 13 '17 at 17:05









                              signullsignull

                              711 silver badge1 bronze badge




                              711 silver badge1 bronze badge










                              • 3





                                Try echo $array[1], you will get null string. And to get three you need to do echo $array[2]. So unset is not the right mechanism to remove an element in bash array.

                                – rashok
                                Apr 3 '18 at 9:23












                              • 3





                                Try echo $array[1], you will get null string. And to get three you need to do echo $array[2]. So unset is not the right mechanism to remove an element in bash array.

                                – rashok
                                Apr 3 '18 at 9:23







                              3




                              3





                              Try echo $array[1], you will get null string. And to get three you need to do echo $array[2]. So unset is not the right mechanism to remove an element in bash array.

                              – rashok
                              Apr 3 '18 at 9:23





                              Try echo $array[1], you will get null string. And to get three you need to do echo $array[2]. So unset is not the right mechanism to remove an element in bash array.

                              – rashok
                              Apr 3 '18 at 9:23











                              4














                              Here's a one-line solution with mapfile:



                              $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "<regexp>")


                              Example:



                              $ arr=("Adam" "Bob" "Claire"$'n'"Smith" "David" "Eve" "Fred")

                              $ echo "Size: $#arr[*] Contents: $arr[*]"

                              Size: 6 Contents: Adam Bob Claire
                              Smith David Eve Fred

                              $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "^ClairenSmith$")

                              $ echo "Size: $#arr[*] Contents: $arr[*]"

                              Size: 5 Contents: Adam Bob David Eve Fred


                              This method allows for great flexibility by modifying/exchanging the grep command and doesn't leave any empty strings in the array.






                              share|improve this answer






















                              • 1





                                Please use printf '%sn' "$array[@]" instead of that ugly IFS/echo thing.

                                – gniourf_gniourf
                                Jan 15 '17 at 19:07












                              • Note that this fails with fields that contain newlines.

                                – gniourf_gniourf
                                Jan 15 '17 at 19:08











                              • I've edited the answer to allow newlines in fields.

                                – Niklas Holm
                                Mar 23 '18 at 8:14











                              • @Socowi You're incorrect, at least on bash 4.4.19. -d $'' works perfectly fine while just -d without the argument does not.

                                – Niklas Holm
                                Mar 27 at 9:13











                              • Ah yes, I mixed it up. Sorry. What I meant was: -d $'' is the same as-d $' something' or just -d ''.

                                – Socowi
                                Mar 27 at 9:27
















                              4














                              Here's a one-line solution with mapfile:



                              $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "<regexp>")


                              Example:



                              $ arr=("Adam" "Bob" "Claire"$'n'"Smith" "David" "Eve" "Fred")

                              $ echo "Size: $#arr[*] Contents: $arr[*]"

                              Size: 6 Contents: Adam Bob Claire
                              Smith David Eve Fred

                              $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "^ClairenSmith$")

                              $ echo "Size: $#arr[*] Contents: $arr[*]"

                              Size: 5 Contents: Adam Bob David Eve Fred


                              This method allows for great flexibility by modifying/exchanging the grep command and doesn't leave any empty strings in the array.






                              share|improve this answer






















                              • 1





                                Please use printf '%sn' "$array[@]" instead of that ugly IFS/echo thing.

                                – gniourf_gniourf
                                Jan 15 '17 at 19:07












                              • Note that this fails with fields that contain newlines.

                                – gniourf_gniourf
                                Jan 15 '17 at 19:08











                              • I've edited the answer to allow newlines in fields.

                                – Niklas Holm
                                Mar 23 '18 at 8:14











                              • @Socowi You're incorrect, at least on bash 4.4.19. -d $'' works perfectly fine while just -d without the argument does not.

                                – Niklas Holm
                                Mar 27 at 9:13











                              • Ah yes, I mixed it up. Sorry. What I meant was: -d $'' is the same as-d $' something' or just -d ''.

                                – Socowi
                                Mar 27 at 9:27














                              4












                              4








                              4







                              Here's a one-line solution with mapfile:



                              $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "<regexp>")


                              Example:



                              $ arr=("Adam" "Bob" "Claire"$'n'"Smith" "David" "Eve" "Fred")

                              $ echo "Size: $#arr[*] Contents: $arr[*]"

                              Size: 6 Contents: Adam Bob Claire
                              Smith David Eve Fred

                              $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "^ClairenSmith$")

                              $ echo "Size: $#arr[*] Contents: $arr[*]"

                              Size: 5 Contents: Adam Bob David Eve Fred


                              This method allows for great flexibility by modifying/exchanging the grep command and doesn't leave any empty strings in the array.






                              share|improve this answer















                              Here's a one-line solution with mapfile:



                              $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "<regexp>")


                              Example:



                              $ arr=("Adam" "Bob" "Claire"$'n'"Smith" "David" "Eve" "Fred")

                              $ echo "Size: $#arr[*] Contents: $arr[*]"

                              Size: 6 Contents: Adam Bob Claire
                              Smith David Eve Fred

                              $ mapfile -d $'' -t arr < <(printf '%s' "$arr[@]" | grep -Pzv "^ClairenSmith$")

                              $ echo "Size: $#arr[*] Contents: $arr[*]"

                              Size: 5 Contents: Adam Bob David Eve Fred


                              This method allows for great flexibility by modifying/exchanging the grep command and doesn't leave any empty strings in the array.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Mar 23 '18 at 8:26

























                              answered Oct 26 '16 at 13:46









                              Niklas HolmNiklas Holm

                              3452 silver badges9 bronze badges




                              3452 silver badges9 bronze badges










                              • 1





                                Please use printf '%sn' "$array[@]" instead of that ugly IFS/echo thing.

                                – gniourf_gniourf
                                Jan 15 '17 at 19:07












                              • Note that this fails with fields that contain newlines.

                                – gniourf_gniourf
                                Jan 15 '17 at 19:08











                              • I've edited the answer to allow newlines in fields.

                                – Niklas Holm
                                Mar 23 '18 at 8:14











                              • @Socowi You're incorrect, at least on bash 4.4.19. -d $'' works perfectly fine while just -d without the argument does not.

                                – Niklas Holm
                                Mar 27 at 9:13











                              • Ah yes, I mixed it up. Sorry. What I meant was: -d $'' is the same as-d $' something' or just -d ''.

                                – Socowi
                                Mar 27 at 9:27













                              • 1





                                Please use printf '%sn' "$array[@]" instead of that ugly IFS/echo thing.

                                – gniourf_gniourf
                                Jan 15 '17 at 19:07












                              • Note that this fails with fields that contain newlines.

                                – gniourf_gniourf
                                Jan 15 '17 at 19:08











                              • I've edited the answer to allow newlines in fields.

                                – Niklas Holm
                                Mar 23 '18 at 8:14











                              • @Socowi You're incorrect, at least on bash 4.4.19. -d $'' works perfectly fine while just -d without the argument does not.

                                – Niklas Holm
                                Mar 27 at 9:13











                              • Ah yes, I mixed it up. Sorry. What I meant was: -d $'' is the same as-d $' something' or just -d ''.

                                – Socowi
                                Mar 27 at 9:27








                              1




                              1





                              Please use printf '%sn' "$array[@]" instead of that ugly IFS/echo thing.

                              – gniourf_gniourf
                              Jan 15 '17 at 19:07






                              Please use printf '%sn' "$array[@]" instead of that ugly IFS/echo thing.

                              – gniourf_gniourf
                              Jan 15 '17 at 19:07














                              Note that this fails with fields that contain newlines.

                              – gniourf_gniourf
                              Jan 15 '17 at 19:08





                              Note that this fails with fields that contain newlines.

                              – gniourf_gniourf
                              Jan 15 '17 at 19:08













                              I've edited the answer to allow newlines in fields.

                              – Niklas Holm
                              Mar 23 '18 at 8:14





                              I've edited the answer to allow newlines in fields.

                              – Niklas Holm
                              Mar 23 '18 at 8:14













                              @Socowi You're incorrect, at least on bash 4.4.19. -d $'' works perfectly fine while just -d without the argument does not.

                              – Niklas Holm
                              Mar 27 at 9:13





                              @Socowi You're incorrect, at least on bash 4.4.19. -d $'' works perfectly fine while just -d without the argument does not.

                              – Niklas Holm
                              Mar 27 at 9:13













                              Ah yes, I mixed it up. Sorry. What I meant was: -d $'' is the same as-d $' something' or just -d ''.

                              – Socowi
                              Mar 27 at 9:27






                              Ah yes, I mixed it up. Sorry. What I meant was: -d $'' is the same as-d $' something' or just -d ''.

                              – Socowi
                              Mar 27 at 9:27












                              2














                              To expand on the above answers, the following can be used to remove multiple elements from an array, without partial matching:



                              ARRAY=(one two onetwo three four threefour "one six")
                              TO_REMOVE=(one four)

                              TEMP_ARRAY=()
                              for pkg in "$ARRAY[@]"; do
                              for remove in "$TO_REMOVE[@]"; do
                              KEEP=true
                              if [[ $pkg == $remove ]]; then
                              KEEP=false
                              break
                              fi
                              done
                              if $KEEP; then
                              TEMP_ARRAY+=($pkg)
                              fi
                              done
                              ARRAY=("$TEMP_ARRAY[@]")
                              unset TEMP_ARRAY


                              This will result in an array containing:
                              (two onetwo three threefour "one six")






                              share|improve this answer





























                                2














                                To expand on the above answers, the following can be used to remove multiple elements from an array, without partial matching:



                                ARRAY=(one two onetwo three four threefour "one six")
                                TO_REMOVE=(one four)

                                TEMP_ARRAY=()
                                for pkg in "$ARRAY[@]"; do
                                for remove in "$TO_REMOVE[@]"; do
                                KEEP=true
                                if [[ $pkg == $remove ]]; then
                                KEEP=false
                                break
                                fi
                                done
                                if $KEEP; then
                                TEMP_ARRAY+=($pkg)
                                fi
                                done
                                ARRAY=("$TEMP_ARRAY[@]")
                                unset TEMP_ARRAY


                                This will result in an array containing:
                                (two onetwo three threefour "one six")






                                share|improve this answer



























                                  2












                                  2








                                  2







                                  To expand on the above answers, the following can be used to remove multiple elements from an array, without partial matching:



                                  ARRAY=(one two onetwo three four threefour "one six")
                                  TO_REMOVE=(one four)

                                  TEMP_ARRAY=()
                                  for pkg in "$ARRAY[@]"; do
                                  for remove in "$TO_REMOVE[@]"; do
                                  KEEP=true
                                  if [[ $pkg == $remove ]]; then
                                  KEEP=false
                                  break
                                  fi
                                  done
                                  if $KEEP; then
                                  TEMP_ARRAY+=($pkg)
                                  fi
                                  done
                                  ARRAY=("$TEMP_ARRAY[@]")
                                  unset TEMP_ARRAY


                                  This will result in an array containing:
                                  (two onetwo three threefour "one six")






                                  share|improve this answer













                                  To expand on the above answers, the following can be used to remove multiple elements from an array, without partial matching:



                                  ARRAY=(one two onetwo three four threefour "one six")
                                  TO_REMOVE=(one four)

                                  TEMP_ARRAY=()
                                  for pkg in "$ARRAY[@]"; do
                                  for remove in "$TO_REMOVE[@]"; do
                                  KEEP=true
                                  if [[ $pkg == $remove ]]; then
                                  KEEP=false
                                  break
                                  fi
                                  done
                                  if $KEEP; then
                                  TEMP_ARRAY+=($pkg)
                                  fi
                                  done
                                  ARRAY=("$TEMP_ARRAY[@]")
                                  unset TEMP_ARRAY


                                  This will result in an array containing:
                                  (two onetwo three threefour "one six")







                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Mar 16 '16 at 9:48









                                  DylanDylan

                                  3512 silver badges6 bronze badges




                                  3512 silver badges6 bronze badges
























                                      2














                                      Here's a (probably very bash-specific) little function involving bash variable indirection and unset; it's a general solution that does not involve text substitution or discarding empty elements and has no problems with quoting/whitespace etc.



                                      delete_ary_elmt() 
                                      local word=$1 # the element to search for & delete
                                      local aryref="$2[@]" # a necessary step since '$!$2[@]' is a syntax error
                                      local arycopy=("$!aryref") # create a copy of the input array
                                      local status=1
                                      for (( i = $#arycopy[@] - 1; i >= 0; i-- )); do # iterate over indices backwards
                                      elmt=$arycopy[$i]
                                      [[ $elmt == $word ]] && unset "$2[$i]" && status=0 # unset matching elmts in orig. ary
                                      done
                                      return $status # return 0 if something was deleted; 1 if not


                                      array=(a 0 0 b 0 0 0 c 0 d e 0 0 0)
                                      delete_ary_elmt 0 array
                                      for e in "$array[@]"; do
                                      echo "$e"
                                      done

                                      # prints "a" "b" "c" "d" in lines


                                      Use it like delete_ary_elmt ELEMENT ARRAYNAME without any $ sigil. Switch the == $word for == $word* for prefix matches; use $elmt,, == $word,, for case-insensitive matches; etc., whatever bash [[ supports.



                                      It works by determining the indices of the input array and iterating over them backwards (so deleting elements doesn't screw up iteration order). To get the indices you need to access the input array by name, which can be done via bash variable indirection x=1; varname=x; echo $!varname # prints "1".



                                      You can't access arrays by name like aryname=a; echo "$$aryname[@], this gives you an error. You can't do aryname=a; echo "$!aryname[@]", this gives you the indices of the variable aryname (although it is not an array). What DOES work is aryref="a[@]"; echo "$!aryref", which will print the elements of the array a, preserving shell-word quoting and whitespace exactly like echo "$a[@]". But this only works for printing the elements of an array, not for printing its length or indices (aryref="!a[@]" or aryref="#a[@]" or "$!!aryref" or "$#!aryref", they all fail).



                                      So I copy the original array by its name via bash indirection and get the indices from the copy. To iterate over the indices in reverse I use a C-style for loop. I could also do it by accessing the indices via $!arycopy[@] and reversing them with tac, which is a cat that turns around the input line order.



                                      A function solution without variable indirection would probably have to involve eval, which may or may not be safe to use in that situation (I can't tell).






                                      share|improve this answer

























                                      • This almost works nicely, however it doesn't redeclare the initial array passed into the function, so while that initial array has its values missing, it also has its indexes messed up. What this mean is that the next call you make to delete_ary_elmt on the same array will not work (or will remove the wrong things). For instance, after what you have pasted, try running delete_ary_elmt "d" array and then re-printing the array. You will see that the wrong element gets removed. Removing the last element will also then never work.

                                        – Scott
                                        Feb 26 '18 at 19:26















                                      2














                                      Here's a (probably very bash-specific) little function involving bash variable indirection and unset; it's a general solution that does not involve text substitution or discarding empty elements and has no problems with quoting/whitespace etc.



                                      delete_ary_elmt() 
                                      local word=$1 # the element to search for & delete
                                      local aryref="$2[@]" # a necessary step since '$!$2[@]' is a syntax error
                                      local arycopy=("$!aryref") # create a copy of the input array
                                      local status=1
                                      for (( i = $#arycopy[@] - 1; i >= 0; i-- )); do # iterate over indices backwards
                                      elmt=$arycopy[$i]
                                      [[ $elmt == $word ]] && unset "$2[$i]" && status=0 # unset matching elmts in orig. ary
                                      done
                                      return $status # return 0 if something was deleted; 1 if not


                                      array=(a 0 0 b 0 0 0 c 0 d e 0 0 0)
                                      delete_ary_elmt 0 array
                                      for e in "$array[@]"; do
                                      echo "$e"
                                      done

                                      # prints "a" "b" "c" "d" in lines


                                      Use it like delete_ary_elmt ELEMENT ARRAYNAME without any $ sigil. Switch the == $word for == $word* for prefix matches; use $elmt,, == $word,, for case-insensitive matches; etc., whatever bash [[ supports.



                                      It works by determining the indices of the input array and iterating over them backwards (so deleting elements doesn't screw up iteration order). To get the indices you need to access the input array by name, which can be done via bash variable indirection x=1; varname=x; echo $!varname # prints "1".



                                      You can't access arrays by name like aryname=a; echo "$$aryname[@], this gives you an error. You can't do aryname=a; echo "$!aryname[@]", this gives you the indices of the variable aryname (although it is not an array). What DOES work is aryref="a[@]"; echo "$!aryref", which will print the elements of the array a, preserving shell-word quoting and whitespace exactly like echo "$a[@]". But this only works for printing the elements of an array, not for printing its length or indices (aryref="!a[@]" or aryref="#a[@]" or "$!!aryref" or "$#!aryref", they all fail).



                                      So I copy the original array by its name via bash indirection and get the indices from the copy. To iterate over the indices in reverse I use a C-style for loop. I could also do it by accessing the indices via $!arycopy[@] and reversing them with tac, which is a cat that turns around the input line order.



                                      A function solution without variable indirection would probably have to involve eval, which may or may not be safe to use in that situation (I can't tell).






                                      share|improve this answer

























                                      • This almost works nicely, however it doesn't redeclare the initial array passed into the function, so while that initial array has its values missing, it also has its indexes messed up. What this mean is that the next call you make to delete_ary_elmt on the same array will not work (or will remove the wrong things). For instance, after what you have pasted, try running delete_ary_elmt "d" array and then re-printing the array. You will see that the wrong element gets removed. Removing the last element will also then never work.

                                        – Scott
                                        Feb 26 '18 at 19:26













                                      2












                                      2








                                      2







                                      Here's a (probably very bash-specific) little function involving bash variable indirection and unset; it's a general solution that does not involve text substitution or discarding empty elements and has no problems with quoting/whitespace etc.



                                      delete_ary_elmt() 
                                      local word=$1 # the element to search for & delete
                                      local aryref="$2[@]" # a necessary step since '$!$2[@]' is a syntax error
                                      local arycopy=("$!aryref") # create a copy of the input array
                                      local status=1
                                      for (( i = $#arycopy[@] - 1; i >= 0; i-- )); do # iterate over indices backwards
                                      elmt=$arycopy[$i]
                                      [[ $elmt == $word ]] && unset "$2[$i]" && status=0 # unset matching elmts in orig. ary
                                      done
                                      return $status # return 0 if something was deleted; 1 if not


                                      array=(a 0 0 b 0 0 0 c 0 d e 0 0 0)
                                      delete_ary_elmt 0 array
                                      for e in "$array[@]"; do
                                      echo "$e"
                                      done

                                      # prints "a" "b" "c" "d" in lines


                                      Use it like delete_ary_elmt ELEMENT ARRAYNAME without any $ sigil. Switch the == $word for == $word* for prefix matches; use $elmt,, == $word,, for case-insensitive matches; etc., whatever bash [[ supports.



                                      It works by determining the indices of the input array and iterating over them backwards (so deleting elements doesn't screw up iteration order). To get the indices you need to access the input array by name, which can be done via bash variable indirection x=1; varname=x; echo $!varname # prints "1".



                                      You can't access arrays by name like aryname=a; echo "$$aryname[@], this gives you an error. You can't do aryname=a; echo "$!aryname[@]", this gives you the indices of the variable aryname (although it is not an array). What DOES work is aryref="a[@]"; echo "$!aryref", which will print the elements of the array a, preserving shell-word quoting and whitespace exactly like echo "$a[@]". But this only works for printing the elements of an array, not for printing its length or indices (aryref="!a[@]" or aryref="#a[@]" or "$!!aryref" or "$#!aryref", they all fail).



                                      So I copy the original array by its name via bash indirection and get the indices from the copy. To iterate over the indices in reverse I use a C-style for loop. I could also do it by accessing the indices via $!arycopy[@] and reversing them with tac, which is a cat that turns around the input line order.



                                      A function solution without variable indirection would probably have to involve eval, which may or may not be safe to use in that situation (I can't tell).






                                      share|improve this answer













                                      Here's a (probably very bash-specific) little function involving bash variable indirection and unset; it's a general solution that does not involve text substitution or discarding empty elements and has no problems with quoting/whitespace etc.



                                      delete_ary_elmt() 
                                      local word=$1 # the element to search for & delete
                                      local aryref="$2[@]" # a necessary step since '$!$2[@]' is a syntax error
                                      local arycopy=("$!aryref") # create a copy of the input array
                                      local status=1
                                      for (( i = $#arycopy[@] - 1; i >= 0; i-- )); do # iterate over indices backwards
                                      elmt=$arycopy[$i]
                                      [[ $elmt == $word ]] && unset "$2[$i]" && status=0 # unset matching elmts in orig. ary
                                      done
                                      return $status # return 0 if something was deleted; 1 if not


                                      array=(a 0 0 b 0 0 0 c 0 d e 0 0 0)
                                      delete_ary_elmt 0 array
                                      for e in "$array[@]"; do
                                      echo "$e"
                                      done

                                      # prints "a" "b" "c" "d" in lines


                                      Use it like delete_ary_elmt ELEMENT ARRAYNAME without any $ sigil. Switch the == $word for == $word* for prefix matches; use $elmt,, == $word,, for case-insensitive matches; etc., whatever bash [[ supports.



                                      It works by determining the indices of the input array and iterating over them backwards (so deleting elements doesn't screw up iteration order). To get the indices you need to access the input array by name, which can be done via bash variable indirection x=1; varname=x; echo $!varname # prints "1".



                                      You can't access arrays by name like aryname=a; echo "$$aryname[@], this gives you an error. You can't do aryname=a; echo "$!aryname[@]", this gives you the indices of the variable aryname (although it is not an array). What DOES work is aryref="a[@]"; echo "$!aryref", which will print the elements of the array a, preserving shell-word quoting and whitespace exactly like echo "$a[@]". But this only works for printing the elements of an array, not for printing its length or indices (aryref="!a[@]" or aryref="#a[@]" or "$!!aryref" or "$#!aryref", they all fail).



                                      So I copy the original array by its name via bash indirection and get the indices from the copy. To iterate over the indices in reverse I use a C-style for loop. I could also do it by accessing the indices via $!arycopy[@] and reversing them with tac, which is a cat that turns around the input line order.



                                      A function solution without variable indirection would probably have to involve eval, which may or may not be safe to use in that situation (I can't tell).







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Jan 15 '17 at 18:17









                                      S.V.P.S.V.P.

                                      211 bronze badge




                                      211 bronze badge















                                      • This almost works nicely, however it doesn't redeclare the initial array passed into the function, so while that initial array has its values missing, it also has its indexes messed up. What this mean is that the next call you make to delete_ary_elmt on the same array will not work (or will remove the wrong things). For instance, after what you have pasted, try running delete_ary_elmt "d" array and then re-printing the array. You will see that the wrong element gets removed. Removing the last element will also then never work.

                                        – Scott
                                        Feb 26 '18 at 19:26

















                                      • This almost works nicely, however it doesn't redeclare the initial array passed into the function, so while that initial array has its values missing, it also has its indexes messed up. What this mean is that the next call you make to delete_ary_elmt on the same array will not work (or will remove the wrong things). For instance, after what you have pasted, try running delete_ary_elmt "d" array and then re-printing the array. You will see that the wrong element gets removed. Removing the last element will also then never work.

                                        – Scott
                                        Feb 26 '18 at 19:26
















                                      This almost works nicely, however it doesn't redeclare the initial array passed into the function, so while that initial array has its values missing, it also has its indexes messed up. What this mean is that the next call you make to delete_ary_elmt on the same array will not work (or will remove the wrong things). For instance, after what you have pasted, try running delete_ary_elmt "d" array and then re-printing the array. You will see that the wrong element gets removed. Removing the last element will also then never work.

                                      – Scott
                                      Feb 26 '18 at 19:26





                                      This almost works nicely, however it doesn't redeclare the initial array passed into the function, so while that initial array has its values missing, it also has its indexes messed up. What this mean is that the next call you make to delete_ary_elmt on the same array will not work (or will remove the wrong things). For instance, after what you have pasted, try running delete_ary_elmt "d" array and then re-printing the array. You will see that the wrong element gets removed. Removing the last element will also then never work.

                                      – Scott
                                      Feb 26 '18 at 19:26











                                      1














                                      Using unset



                                      To remove an element at particular index, we can use unset and then do copy to another array. Only just unset is not required in this case. Because unset does not remove the element it just sets null string to the particular index in array.



                                      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]"


                                      Output is



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


                                      Using :<idx>



                                      We can remove some set of elements using :<idx> also. For example if we want to remove 1st element we can use :1 as mentioned below.



                                      declare -a arr=('aa' 'bb' 'cc' 'dd' 'ee')
                                      arr2=("$arr[@]:1")
                                      echo "$arr2[@]"
                                      echo "1st val is $arr2[1], 2nd val is $arr2[2]"


                                      Output is



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





                                      share|improve this answer































                                        1














                                        Using unset



                                        To remove an element at particular index, we can use unset and then do copy to another array. Only just unset is not required in this case. Because unset does not remove the element it just sets null string to the particular index in array.



                                        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]"


                                        Output is



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


                                        Using :<idx>



                                        We can remove some set of elements using :<idx> also. For example if we want to remove 1st element we can use :1 as mentioned below.



                                        declare -a arr=('aa' 'bb' 'cc' 'dd' 'ee')
                                        arr2=("$arr[@]:1")
                                        echo "$arr2[@]"
                                        echo "1st val is $arr2[1], 2nd val is $arr2[2]"


                                        Output is



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





                                        share|improve this answer





























                                          1












                                          1








                                          1







                                          Using unset



                                          To remove an element at particular index, we can use unset and then do copy to another array. Only just unset is not required in this case. Because unset does not remove the element it just sets null string to the particular index in array.



                                          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]"


                                          Output is



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


                                          Using :<idx>



                                          We can remove some set of elements using :<idx> also. For example if we want to remove 1st element we can use :1 as mentioned below.



                                          declare -a arr=('aa' 'bb' 'cc' 'dd' 'ee')
                                          arr2=("$arr[@]:1")
                                          echo "$arr2[@]"
                                          echo "1st val is $arr2[1], 2nd val is $arr2[2]"


                                          Output is



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





                                          share|improve this answer















                                          Using unset



                                          To remove an element at particular index, we can use unset and then do copy to another array. Only just unset is not required in this case. Because unset does not remove the element it just sets null string to the particular index in array.



                                          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]"


                                          Output is



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


                                          Using :<idx>



                                          We can remove some set of elements using :<idx> also. For example if we want to remove 1st element we can use :1 as mentioned below.



                                          declare -a arr=('aa' 'bb' 'cc' 'dd' 'ee')
                                          arr2=("$arr[@]:1")
                                          echo "$arr2[@]"
                                          echo "1st val is $arr2[1], 2nd val is $arr2[2]"


                                          Output is



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






                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited Jan 25 at 17:16









                                          gniourf_gniourf

                                          32.3k5 gold badges69 silver badges84 bronze badges




                                          32.3k5 gold badges69 silver badges84 bronze badges










                                          answered Apr 3 '18 at 9:43









                                          rashokrashok

                                          6,55811 gold badges57 silver badges79 bronze badges




                                          6,55811 gold badges57 silver badges79 bronze badges
























                                              0














                                              POSIX shell script does not have arrays.



                                              So most probably you are using a specific dialect such as bash, korn shells or zsh.



                                              Therefore, your question as of now cannot be answered.



                                              Maybe this works for you:



                                              unset array[$delete]





                                              share|improve this answer




















                                              • 2





                                                Hi, I'm using bash shell atm. And "$delete" is not the position of the element but the string itself. So I don't think "unset" will work

                                                – Alex
                                                May 31 '13 at 16:07
















                                              0














                                              POSIX shell script does not have arrays.



                                              So most probably you are using a specific dialect such as bash, korn shells or zsh.



                                              Therefore, your question as of now cannot be answered.



                                              Maybe this works for you:



                                              unset array[$delete]





                                              share|improve this answer




















                                              • 2





                                                Hi, I'm using bash shell atm. And "$delete" is not the position of the element but the string itself. So I don't think "unset" will work

                                                – Alex
                                                May 31 '13 at 16:07














                                              0












                                              0








                                              0







                                              POSIX shell script does not have arrays.



                                              So most probably you are using a specific dialect such as bash, korn shells or zsh.



                                              Therefore, your question as of now cannot be answered.



                                              Maybe this works for you:



                                              unset array[$delete]





                                              share|improve this answer













                                              POSIX shell script does not have arrays.



                                              So most probably you are using a specific dialect such as bash, korn shells or zsh.



                                              Therefore, your question as of now cannot be answered.



                                              Maybe this works for you:



                                              unset array[$delete]






                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered May 31 '13 at 15:38









                                              Anony-MousseAnony-Mousse

                                              61.3k8 gold badges100 silver badges166 bronze badges




                                              61.3k8 gold badges100 silver badges166 bronze badges










                                              • 2





                                                Hi, I'm using bash shell atm. And "$delete" is not the position of the element but the string itself. So I don't think "unset" will work

                                                – Alex
                                                May 31 '13 at 16:07













                                              • 2





                                                Hi, I'm using bash shell atm. And "$delete" is not the position of the element but the string itself. So I don't think "unset" will work

                                                – Alex
                                                May 31 '13 at 16:07








                                              2




                                              2





                                              Hi, I'm using bash shell atm. And "$delete" is not the position of the element but the string itself. So I don't think "unset" will work

                                              – Alex
                                              May 31 '13 at 16:07






                                              Hi, I'm using bash shell atm. And "$delete" is not the position of the element but the string itself. So I don't think "unset" will work

                                              – Alex
                                              May 31 '13 at 16:07












                                              0














                                              Actually, I just noticed that the shell syntax somewhat has a behavior built-in that allows for easy reconstruction of the array when, as posed in the question, an item should be removed.



                                              # let's set up an array of items to consume:
                                              x=()
                                              for (( i=0; i<10; i++ )); do
                                              x+=("$i")
                                              done

                                              # here, we consume that array:
                                              while (( $#x[@] )); do
                                              i=$(( $RANDOM % $#x[@] ))
                                              echo "$x[i] / $x[@]"
                                              x=("$x[@]:0:i" "$x[@]:i+1")
                                              done


                                              Notice how we constructed the array using bash's x+=() syntax?



                                              You could actually add more than one item with that, the content of a whole other array at once.






                                              share|improve this answer































                                                0














                                                Actually, I just noticed that the shell syntax somewhat has a behavior built-in that allows for easy reconstruction of the array when, as posed in the question, an item should be removed.



                                                # let's set up an array of items to consume:
                                                x=()
                                                for (( i=0; i<10; i++ )); do
                                                x+=("$i")
                                                done

                                                # here, we consume that array:
                                                while (( $#x[@] )); do
                                                i=$(( $RANDOM % $#x[@] ))
                                                echo "$x[i] / $x[@]"
                                                x=("$x[@]:0:i" "$x[@]:i+1")
                                                done


                                                Notice how we constructed the array using bash's x+=() syntax?



                                                You could actually add more than one item with that, the content of a whole other array at once.






                                                share|improve this answer





























                                                  0












                                                  0








                                                  0







                                                  Actually, I just noticed that the shell syntax somewhat has a behavior built-in that allows for easy reconstruction of the array when, as posed in the question, an item should be removed.



                                                  # let's set up an array of items to consume:
                                                  x=()
                                                  for (( i=0; i<10; i++ )); do
                                                  x+=("$i")
                                                  done

                                                  # here, we consume that array:
                                                  while (( $#x[@] )); do
                                                  i=$(( $RANDOM % $#x[@] ))
                                                  echo "$x[i] / $x[@]"
                                                  x=("$x[@]:0:i" "$x[@]:i+1")
                                                  done


                                                  Notice how we constructed the array using bash's x+=() syntax?



                                                  You could actually add more than one item with that, the content of a whole other array at once.






                                                  share|improve this answer















                                                  Actually, I just noticed that the shell syntax somewhat has a behavior built-in that allows for easy reconstruction of the array when, as posed in the question, an item should be removed.



                                                  # let's set up an array of items to consume:
                                                  x=()
                                                  for (( i=0; i<10; i++ )); do
                                                  x+=("$i")
                                                  done

                                                  # here, we consume that array:
                                                  while (( $#x[@] )); do
                                                  i=$(( $RANDOM % $#x[@] ))
                                                  echo "$x[i] / $x[@]"
                                                  x=("$x[@]:0:i" "$x[@]:i+1")
                                                  done


                                                  Notice how we constructed the array using bash's x+=() syntax?



                                                  You could actually add more than one item with that, the content of a whole other array at once.







                                                  share|improve this answer














                                                  share|improve this answer



                                                  share|improve this answer








                                                  edited Dec 21 '16 at 7:25

























                                                  answered Dec 21 '16 at 7:20









                                                  mar77imar77i

                                                  826 bronze badges




                                                  826 bronze badges
























                                                      0














                                                      http://wiki.bash-hackers.org/syntax/pe#substring_removal




                                                      $PARAMETER#PATTERN # remove from beginning



                                                      $PARAMETER##PATTERN # remove from the beginning, greedy match



                                                      $PARAMETER%PATTERN # remove from the end



                                                      $PARAMETER%%PATTERN # remove from the end, greedy match




                                                      In order to do a full remove element, you have to do an unset command with an if statement. If you don't care about removing prefixes from other variables or about supporting whitespace in the array, then you can just drop the quotes and forget about for loops.



                                                      See example below for a few different ways to clean up an array.



                                                      options=("foo" "bar" "foo" "foobar" "foo bar" "bars" "bar")

                                                      # remove bar from the start of each element
                                                      options=("$options[@]/#"bar"")
                                                      # options=("foo" "" "foo" "foobar" "foo bar" "s" "")

                                                      # remove the complete string "foo" in a for loop
                                                      count=$#options[@]
                                                      for ((i = 0; i < count; i++)); do
                                                      if [ "$options[i]" = "foo" ] ; then
                                                      unset 'options[i]'
                                                      fi
                                                      done
                                                      # options=( "" "foobar" "foo bar" "s" "")

                                                      # remove empty options
                                                      # note the count variable can't be recalculated easily on a sparse array
                                                      for ((i = 0; i < count; i++)); do
                                                      # echo "Element $i: '$options[i]'"
                                                      if [ -z "$options[i]" ] ; then
                                                      unset 'options[i]'
                                                      fi
                                                      done
                                                      # options=("foobar" "foo bar" "s")

                                                      # list them with select
                                                      echo "Choose an option:"
                                                      PS3='Option? '
                                                      select i in "$options[@]" Quit
                                                      do
                                                      case $i in
                                                      Quit) break ;;
                                                      *) echo "You selected "$i"" ;;
                                                      esac
                                                      done


                                                      Output



                                                      Choose an option:
                                                      1) foobar
                                                      2) foo bar
                                                      3) s
                                                      4) Quit
                                                      Option?


                                                      Hope that helps.






                                                      share|improve this answer































                                                        0














                                                        http://wiki.bash-hackers.org/syntax/pe#substring_removal




                                                        $PARAMETER#PATTERN # remove from beginning



                                                        $PARAMETER##PATTERN # remove from the beginning, greedy match



                                                        $PARAMETER%PATTERN # remove from the end



                                                        $PARAMETER%%PATTERN # remove from the end, greedy match




                                                        In order to do a full remove element, you have to do an unset command with an if statement. If you don't care about removing prefixes from other variables or about supporting whitespace in the array, then you can just drop the quotes and forget about for loops.



                                                        See example below for a few different ways to clean up an array.



                                                        options=("foo" "bar" "foo" "foobar" "foo bar" "bars" "bar")

                                                        # remove bar from the start of each element
                                                        options=("$options[@]/#"bar"")
                                                        # options=("foo" "" "foo" "foobar" "foo bar" "s" "")

                                                        # remove the complete string "foo" in a for loop
                                                        count=$#options[@]
                                                        for ((i = 0; i < count; i++)); do
                                                        if [ "$options[i]" = "foo" ] ; then
                                                        unset 'options[i]'
                                                        fi
                                                        done
                                                        # options=( "" "foobar" "foo bar" "s" "")

                                                        # remove empty options
                                                        # note the count variable can't be recalculated easily on a sparse array
                                                        for ((i = 0; i < count; i++)); do
                                                        # echo "Element $i: '$options[i]'"
                                                        if [ -z "$options[i]" ] ; then
                                                        unset 'options[i]'
                                                        fi
                                                        done
                                                        # options=("foobar" "foo bar" "s")

                                                        # list them with select
                                                        echo "Choose an option:"
                                                        PS3='Option? '
                                                        select i in "$options[@]" Quit
                                                        do
                                                        case $i in
                                                        Quit) break ;;
                                                        *) echo "You selected "$i"" ;;
                                                        esac
                                                        done


                                                        Output



                                                        Choose an option:
                                                        1) foobar
                                                        2) foo bar
                                                        3) s
                                                        4) Quit
                                                        Option?


                                                        Hope that helps.






                                                        share|improve this answer





























                                                          0












                                                          0








                                                          0







                                                          http://wiki.bash-hackers.org/syntax/pe#substring_removal




                                                          $PARAMETER#PATTERN # remove from beginning



                                                          $PARAMETER##PATTERN # remove from the beginning, greedy match



                                                          $PARAMETER%PATTERN # remove from the end



                                                          $PARAMETER%%PATTERN # remove from the end, greedy match




                                                          In order to do a full remove element, you have to do an unset command with an if statement. If you don't care about removing prefixes from other variables or about supporting whitespace in the array, then you can just drop the quotes and forget about for loops.



                                                          See example below for a few different ways to clean up an array.



                                                          options=("foo" "bar" "foo" "foobar" "foo bar" "bars" "bar")

                                                          # remove bar from the start of each element
                                                          options=("$options[@]/#"bar"")
                                                          # options=("foo" "" "foo" "foobar" "foo bar" "s" "")

                                                          # remove the complete string "foo" in a for loop
                                                          count=$#options[@]
                                                          for ((i = 0; i < count; i++)); do
                                                          if [ "$options[i]" = "foo" ] ; then
                                                          unset 'options[i]'
                                                          fi
                                                          done
                                                          # options=( "" "foobar" "foo bar" "s" "")

                                                          # remove empty options
                                                          # note the count variable can't be recalculated easily on a sparse array
                                                          for ((i = 0; i < count; i++)); do
                                                          # echo "Element $i: '$options[i]'"
                                                          if [ -z "$options[i]" ] ; then
                                                          unset 'options[i]'
                                                          fi
                                                          done
                                                          # options=("foobar" "foo bar" "s")

                                                          # list them with select
                                                          echo "Choose an option:"
                                                          PS3='Option? '
                                                          select i in "$options[@]" Quit
                                                          do
                                                          case $i in
                                                          Quit) break ;;
                                                          *) echo "You selected "$i"" ;;
                                                          esac
                                                          done


                                                          Output



                                                          Choose an option:
                                                          1) foobar
                                                          2) foo bar
                                                          3) s
                                                          4) Quit
                                                          Option?


                                                          Hope that helps.






                                                          share|improve this answer















                                                          http://wiki.bash-hackers.org/syntax/pe#substring_removal




                                                          $PARAMETER#PATTERN # remove from beginning



                                                          $PARAMETER##PATTERN # remove from the beginning, greedy match



                                                          $PARAMETER%PATTERN # remove from the end



                                                          $PARAMETER%%PATTERN # remove from the end, greedy match




                                                          In order to do a full remove element, you have to do an unset command with an if statement. If you don't care about removing prefixes from other variables or about supporting whitespace in the array, then you can just drop the quotes and forget about for loops.



                                                          See example below for a few different ways to clean up an array.



                                                          options=("foo" "bar" "foo" "foobar" "foo bar" "bars" "bar")

                                                          # remove bar from the start of each element
                                                          options=("$options[@]/#"bar"")
                                                          # options=("foo" "" "foo" "foobar" "foo bar" "s" "")

                                                          # remove the complete string "foo" in a for loop
                                                          count=$#options[@]
                                                          for ((i = 0; i < count; i++)); do
                                                          if [ "$options[i]" = "foo" ] ; then
                                                          unset 'options[i]'
                                                          fi
                                                          done
                                                          # options=( "" "foobar" "foo bar" "s" "")

                                                          # remove empty options
                                                          # note the count variable can't be recalculated easily on a sparse array
                                                          for ((i = 0; i < count; i++)); do
                                                          # echo "Element $i: '$options[i]'"
                                                          if [ -z "$options[i]" ] ; then
                                                          unset 'options[i]'
                                                          fi
                                                          done
                                                          # options=("foobar" "foo bar" "s")

                                                          # list them with select
                                                          echo "Choose an option:"
                                                          PS3='Option? '
                                                          select i in "$options[@]" Quit
                                                          do
                                                          case $i in
                                                          Quit) break ;;
                                                          *) echo "You selected "$i"" ;;
                                                          esac
                                                          done


                                                          Output



                                                          Choose an option:
                                                          1) foobar
                                                          2) foo bar
                                                          3) s
                                                          4) Quit
                                                          Option?


                                                          Hope that helps.







                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited Jan 15 '17 at 19:05









                                                          gniourf_gniourf

                                                          32.3k5 gold badges69 silver badges84 bronze badges




                                                          32.3k5 gold badges69 silver badges84 bronze badges










                                                          answered Nov 16 '16 at 20:47









                                                          phyattphyatt

                                                          14.8k2 gold badges35 silver badges54 bronze badges




                                                          14.8k2 gold badges35 silver badges54 bronze badges
























                                                              0














                                                              In ZSH this is dead easy (note this uses more bash compatible syntax than necessary where possible for ease of understanding):



                                                              # I always include an edge case to make sure each element
                                                              # is not being word split.
                                                              start=(one two three 'four 4' five)
                                                              work=($(@)start)

                                                              idx=2
                                                              val=$work[idx]

                                                              # How to remove a single element easily.
                                                              # Also works for associative arrays (at least in zsh)
                                                              work[$idx]=()

                                                              echo "Array size went down by one: "
                                                              [[ $#work -eq $(($#start - 1)) ]] && echo "OK"

                                                              echo "Array item "$val" is now gone: "
                                                              [[ -z $work[(r)$val] ]] && echo OK

                                                              echo "Array contents are as expected: "
                                                              wanted=("$start[@]:0:1" "$start[@]:2")
                                                              [[ "$(j.:.)wanted[@]" == "$(j.:.)work[@]" ]] && echo "OK"

                                                              echo "-- array contents: start --"
                                                              print -l -r -- "-- $#start elements" $(@)start
                                                              echo "-- array contents: work --"
                                                              print -l -r -- "-- $#work elements" "$work[@]"


                                                              Results:



                                                              Array size went down by one:
                                                              OK
                                                              Array item two is now gone:
                                                              OK
                                                              Array contents are as expected:
                                                              OK
                                                              -- array contents: start --
                                                              -- 5 elements
                                                              one
                                                              two
                                                              three
                                                              four 4
                                                              five
                                                              -- array contents: work --
                                                              -- 4 elements
                                                              one
                                                              three
                                                              four 4
                                                              five





                                                              share|improve this answer



























                                                              • Sorry, just tried. It did not work in zsh for an assoziative array

                                                                – Falk
                                                                Dec 8 '18 at 22:43












                                                              • It works just fine, I just tested it (again). Things not working for you? Please explain what did not work exactly in as much detail as you can. What ZSH version are you using?

                                                                – trevorj
                                                                Apr 2 at 2:51
















                                                              0














                                                              In ZSH this is dead easy (note this uses more bash compatible syntax than necessary where possible for ease of understanding):



                                                              # I always include an edge case to make sure each element
                                                              # is not being word split.
                                                              start=(one two three 'four 4' five)
                                                              work=($(@)start)

                                                              idx=2
                                                              val=$work[idx]

                                                              # How to remove a single element easily.
                                                              # Also works for associative arrays (at least in zsh)
                                                              work[$idx]=()

                                                              echo "Array size went down by one: "
                                                              [[ $#work -eq $(($#start - 1)) ]] && echo "OK"

                                                              echo "Array item "$val" is now gone: "
                                                              [[ -z $work[(r)$val] ]] && echo OK

                                                              echo "Array contents are as expected: "
                                                              wanted=("$start[@]:0:1" "$start[@]:2")
                                                              [[ "$(j.:.)wanted[@]" == "$(j.:.)work[@]" ]] && echo "OK"

                                                              echo "-- array contents: start --"
                                                              print -l -r -- "-- $#start elements" $(@)start
                                                              echo "-- array contents: work --"
                                                              print -l -r -- "-- $#work elements" "$work[@]"


                                                              Results:



                                                              Array size went down by one:
                                                              OK
                                                              Array item two is now gone:
                                                              OK
                                                              Array contents are as expected:
                                                              OK
                                                              -- array contents: start --
                                                              -- 5 elements
                                                              one
                                                              two
                                                              three
                                                              four 4
                                                              five
                                                              -- array contents: work --
                                                              -- 4 elements
                                                              one
                                                              three
                                                              four 4
                                                              five





                                                              share|improve this answer



























                                                              • Sorry, just tried. It did not work in zsh for an assoziative array

                                                                – Falk
                                                                Dec 8 '18 at 22:43












                                                              • It works just fine, I just tested it (again). Things not working for you? Please explain what did not work exactly in as much detail as you can. What ZSH version are you using?

                                                                – trevorj
                                                                Apr 2 at 2:51














                                                              0












                                                              0








                                                              0







                                                              In ZSH this is dead easy (note this uses more bash compatible syntax than necessary where possible for ease of understanding):



                                                              # I always include an edge case to make sure each element
                                                              # is not being word split.
                                                              start=(one two three 'four 4' five)
                                                              work=($(@)start)

                                                              idx=2
                                                              val=$work[idx]

                                                              # How to remove a single element easily.
                                                              # Also works for associative arrays (at least in zsh)
                                                              work[$idx]=()

                                                              echo "Array size went down by one: "
                                                              [[ $#work -eq $(($#start - 1)) ]] && echo "OK"

                                                              echo "Array item "$val" is now gone: "
                                                              [[ -z $work[(r)$val] ]] && echo OK

                                                              echo "Array contents are as expected: "
                                                              wanted=("$start[@]:0:1" "$start[@]:2")
                                                              [[ "$(j.:.)wanted[@]" == "$(j.:.)work[@]" ]] && echo "OK"

                                                              echo "-- array contents: start --"
                                                              print -l -r -- "-- $#start elements" $(@)start
                                                              echo "-- array contents: work --"
                                                              print -l -r -- "-- $#work elements" "$work[@]"


                                                              Results:



                                                              Array size went down by one:
                                                              OK
                                                              Array item two is now gone:
                                                              OK
                                                              Array contents are as expected:
                                                              OK
                                                              -- array contents: start --
                                                              -- 5 elements
                                                              one
                                                              two
                                                              three
                                                              four 4
                                                              five
                                                              -- array contents: work --
                                                              -- 4 elements
                                                              one
                                                              three
                                                              four 4
                                                              five





                                                              share|improve this answer















                                                              In ZSH this is dead easy (note this uses more bash compatible syntax than necessary where possible for ease of understanding):



                                                              # I always include an edge case to make sure each element
                                                              # is not being word split.
                                                              start=(one two three 'four 4' five)
                                                              work=($(@)start)

                                                              idx=2
                                                              val=$work[idx]

                                                              # How to remove a single element easily.
                                                              # Also works for associative arrays (at least in zsh)
                                                              work[$idx]=()

                                                              echo "Array size went down by one: "
                                                              [[ $#work -eq $(($#start - 1)) ]] && echo "OK"

                                                              echo "Array item "$val" is now gone: "
                                                              [[ -z $work[(r)$val] ]] && echo OK

                                                              echo "Array contents are as expected: "
                                                              wanted=("$start[@]:0:1" "$start[@]:2")
                                                              [[ "$(j.:.)wanted[@]" == "$(j.:.)work[@]" ]] && echo "OK"

                                                              echo "-- array contents: start --"
                                                              print -l -r -- "-- $#start elements" $(@)start
                                                              echo "-- array contents: work --"
                                                              print -l -r -- "-- $#work elements" "$work[@]"


                                                              Results:



                                                              Array size went down by one:
                                                              OK
                                                              Array item two is now gone:
                                                              OK
                                                              Array contents are as expected:
                                                              OK
                                                              -- array contents: start --
                                                              -- 5 elements
                                                              one
                                                              two
                                                              three
                                                              four 4
                                                              five
                                                              -- array contents: work --
                                                              -- 4 elements
                                                              one
                                                              three
                                                              four 4
                                                              five






                                                              share|improve this answer














                                                              share|improve this answer



                                                              share|improve this answer








                                                              edited Aug 11 '18 at 8:22

























                                                              answered Apr 9 '16 at 10:11









                                                              trevorjtrevorj

                                                              743 bronze badges




                                                              743 bronze badges















                                                              • Sorry, just tried. It did not work in zsh for an assoziative array

                                                                – Falk
                                                                Dec 8 '18 at 22:43












                                                              • It works just fine, I just tested it (again). Things not working for you? Please explain what did not work exactly in as much detail as you can. What ZSH version are you using?

                                                                – trevorj
                                                                Apr 2 at 2:51


















                                                              • Sorry, just tried. It did not work in zsh for an assoziative array

                                                                – Falk
                                                                Dec 8 '18 at 22:43












                                                              • It works just fine, I just tested it (again). Things not working for you? Please explain what did not work exactly in as much detail as you can. What ZSH version are you using?

                                                                – trevorj
                                                                Apr 2 at 2:51

















                                                              Sorry, just tried. It did not work in zsh for an assoziative array

                                                              – Falk
                                                              Dec 8 '18 at 22:43






                                                              Sorry, just tried. It did not work in zsh for an assoziative array

                                                              – Falk
                                                              Dec 8 '18 at 22:43














                                                              It works just fine, I just tested it (again). Things not working for you? Please explain what did not work exactly in as much detail as you can. What ZSH version are you using?

                                                              – trevorj
                                                              Apr 2 at 2:51






                                                              It works just fine, I just tested it (again). Things not working for you? Please explain what did not work exactly in as much detail as you can. What ZSH version are you using?

                                                              – trevorj
                                                              Apr 2 at 2:51












                                                              0














                                                              There is also this syntax, e.g. if you want to delete the 2nd element :



                                                              array=("$array[@]:0:1" "$array[@]:2")


                                                              which is in fact the concatenation of 2 tabs. The first from the index 0 to the index 1 (exclusive) and the 2nd from the index 2 to the end.






                                                              share|improve this answer































                                                                0














                                                                There is also this syntax, e.g. if you want to delete the 2nd element :



                                                                array=("$array[@]:0:1" "$array[@]:2")


                                                                which is in fact the concatenation of 2 tabs. The first from the index 0 to the index 1 (exclusive) and the 2nd from the index 2 to the end.






                                                                share|improve this answer





























                                                                  0












                                                                  0








                                                                  0







                                                                  There is also this syntax, e.g. if you want to delete the 2nd element :



                                                                  array=("$array[@]:0:1" "$array[@]:2")


                                                                  which is in fact the concatenation of 2 tabs. The first from the index 0 to the index 1 (exclusive) and the 2nd from the index 2 to the end.






                                                                  share|improve this answer















                                                                  There is also this syntax, e.g. if you want to delete the 2nd element :



                                                                  array=("$array[@]:0:1" "$array[@]:2")


                                                                  which is in fact the concatenation of 2 tabs. The first from the index 0 to the index 1 (exclusive) and the 2nd from the index 2 to the end.







                                                                  share|improve this answer














                                                                  share|improve this answer



                                                                  share|improve this answer








                                                                  edited Jan 25 at 17:14









                                                                  gniourf_gniourf

                                                                  32.3k5 gold badges69 silver badges84 bronze badges




                                                                  32.3k5 gold badges69 silver badges84 bronze badges










                                                                  answered Jan 25 at 17:01









                                                                  OphyTeOphyTe

                                                                  338 bronze badges




                                                                  338 bronze badges
























                                                                      0














                                                                      Partial answer only



                                                                      To delete the first item in the array



                                                                      unset 'array[0]'


                                                                      To delete the last item in the array



                                                                      unset 'array[-1]'





                                                                      share|improve this answer































                                                                        0














                                                                        Partial answer only



                                                                        To delete the first item in the array



                                                                        unset 'array[0]'


                                                                        To delete the last item in the array



                                                                        unset 'array[-1]'





                                                                        share|improve this answer





























                                                                          0












                                                                          0








                                                                          0







                                                                          Partial answer only



                                                                          To delete the first item in the array



                                                                          unset 'array[0]'


                                                                          To delete the last item in the array



                                                                          unset 'array[-1]'





                                                                          share|improve this answer















                                                                          Partial answer only



                                                                          To delete the first item in the array



                                                                          unset 'array[0]'


                                                                          To delete the last item in the array



                                                                          unset 'array[-1]'






                                                                          share|improve this answer














                                                                          share|improve this answer



                                                                          share|improve this answer








                                                                          edited Jan 25 at 17:15









                                                                          gniourf_gniourf

                                                                          32.3k5 gold badges69 silver badges84 bronze badges




                                                                          32.3k5 gold badges69 silver badges84 bronze badges










                                                                          answered Aug 19 '18 at 9:17









                                                                          consideRatioconsideRatio

                                                                          7069 silver badges14 bronze badges




                                                                          7069 silver badges14 bronze badges
























                                                                              0














                                                                              To avoid conflicts with array index using unset - see https://stackoverflow.com/a/49626928/3223785 and https://stackoverflow.com/a/47798640/3223785 for more information - reassign the array to itself: ARRAY_VAR=($ARRAY_VAR[@]).



                                                                              #!/bin/bash

                                                                              ARRAY_VAR=(0 1 2 3 4 5 6 7 8 9)
                                                                              unset ARRAY_VAR[5]
                                                                              unset ARRAY_VAR[4]
                                                                              ARRAY_VAR=($ARRAY_VAR[@])
                                                                              echo $ARRAY_VAR[@]
                                                                              A_LENGTH=$#ARRAY_VAR[*]
                                                                              for (( i=0; i<=$(( $A_LENGTH -1 )); i++ )) ; do
                                                                              echo ""
                                                                              echo "INDEX - $i"
                                                                              echo "VALUE - $ARRAY_VAR[$i]"
                                                                              done

                                                                              exit 0


                                                                              [Ref.: https://tecadmin.net/working-with-array-bash-script/ ]






                                                                              share|improve this answer





























                                                                                0














                                                                                To avoid conflicts with array index using unset - see https://stackoverflow.com/a/49626928/3223785 and https://stackoverflow.com/a/47798640/3223785 for more information - reassign the array to itself: ARRAY_VAR=($ARRAY_VAR[@]).



                                                                                #!/bin/bash

                                                                                ARRAY_VAR=(0 1 2 3 4 5 6 7 8 9)
                                                                                unset ARRAY_VAR[5]
                                                                                unset ARRAY_VAR[4]
                                                                                ARRAY_VAR=($ARRAY_VAR[@])
                                                                                echo $ARRAY_VAR[@]
                                                                                A_LENGTH=$#ARRAY_VAR[*]
                                                                                for (( i=0; i<=$(( $A_LENGTH -1 )); i++ )) ; do
                                                                                echo ""
                                                                                echo "INDEX - $i"
                                                                                echo "VALUE - $ARRAY_VAR[$i]"
                                                                                done

                                                                                exit 0


                                                                                [Ref.: https://tecadmin.net/working-with-array-bash-script/ ]






                                                                                share|improve this answer



























                                                                                  0












                                                                                  0








                                                                                  0







                                                                                  To avoid conflicts with array index using unset - see https://stackoverflow.com/a/49626928/3223785 and https://stackoverflow.com/a/47798640/3223785 for more information - reassign the array to itself: ARRAY_VAR=($ARRAY_VAR[@]).



                                                                                  #!/bin/bash

                                                                                  ARRAY_VAR=(0 1 2 3 4 5 6 7 8 9)
                                                                                  unset ARRAY_VAR[5]
                                                                                  unset ARRAY_VAR[4]
                                                                                  ARRAY_VAR=($ARRAY_VAR[@])
                                                                                  echo $ARRAY_VAR[@]
                                                                                  A_LENGTH=$#ARRAY_VAR[*]
                                                                                  for (( i=0; i<=$(( $A_LENGTH -1 )); i++ )) ; do
                                                                                  echo ""
                                                                                  echo "INDEX - $i"
                                                                                  echo "VALUE - $ARRAY_VAR[$i]"
                                                                                  done

                                                                                  exit 0


                                                                                  [Ref.: https://tecadmin.net/working-with-array-bash-script/ ]






                                                                                  share|improve this answer













                                                                                  To avoid conflicts with array index using unset - see https://stackoverflow.com/a/49626928/3223785 and https://stackoverflow.com/a/47798640/3223785 for more information - reassign the array to itself: ARRAY_VAR=($ARRAY_VAR[@]).



                                                                                  #!/bin/bash

                                                                                  ARRAY_VAR=(0 1 2 3 4 5 6 7 8 9)
                                                                                  unset ARRAY_VAR[5]
                                                                                  unset ARRAY_VAR[4]
                                                                                  ARRAY_VAR=($ARRAY_VAR[@])
                                                                                  echo $ARRAY_VAR[@]
                                                                                  A_LENGTH=$#ARRAY_VAR[*]
                                                                                  for (( i=0; i<=$(( $A_LENGTH -1 )); i++ )) ; do
                                                                                  echo ""
                                                                                  echo "INDEX - $i"
                                                                                  echo "VALUE - $ARRAY_VAR[$i]"
                                                                                  done

                                                                                  exit 0


                                                                                  [Ref.: https://tecadmin.net/working-with-array-bash-script/ ]







                                                                                  share|improve this answer












                                                                                  share|improve this answer



                                                                                  share|improve this answer










                                                                                  answered Jun 21 at 15:11









                                                                                  Eduardo LucioEduardo Lucio

                                                                                  4266 silver badges16 bronze badges




                                                                                  4266 silver badges16 bronze badges
























                                                                                      -1














                                                                                      What I do is:



                                                                                      array="$(echo $array | tr ' ' 'n' | sed "/itemtodelete/d")"


                                                                                      BAM, that item is removed.






                                                                                      share|improve this answer






















                                                                                      • 1





                                                                                        This breaks for array=('first item' 'second item').

                                                                                        – Benjamin W.
                                                                                        Jun 14 '16 at 17:17















                                                                                      -1














                                                                                      What I do is:



                                                                                      array="$(echo $array | tr ' ' 'n' | sed "/itemtodelete/d")"


                                                                                      BAM, that item is removed.






                                                                                      share|improve this answer






















                                                                                      • 1





                                                                                        This breaks for array=('first item' 'second item').

                                                                                        – Benjamin W.
                                                                                        Jun 14 '16 at 17:17













                                                                                      -1












                                                                                      -1








                                                                                      -1







                                                                                      What I do is:



                                                                                      array="$(echo $array | tr ' ' 'n' | sed "/itemtodelete/d")"


                                                                                      BAM, that item is removed.






                                                                                      share|improve this answer















                                                                                      What I do is:



                                                                                      array="$(echo $array | tr ' ' 'n' | sed "/itemtodelete/d")"


                                                                                      BAM, that item is removed.







                                                                                      share|improve this answer














                                                                                      share|improve this answer



                                                                                      share|improve this answer








                                                                                      edited May 24 '16 at 17:34









                                                                                      zx485

                                                                                      16.8k13 gold badges32 silver badges48 bronze badges




                                                                                      16.8k13 gold badges32 silver badges48 bronze badges










                                                                                      answered May 24 '16 at 17:13









                                                                                      garfieldgarfield

                                                                                      71 bronze badge




                                                                                      71 bronze badge










                                                                                      • 1





                                                                                        This breaks for array=('first item' 'second item').

                                                                                        – Benjamin W.
                                                                                        Jun 14 '16 at 17:17












                                                                                      • 1





                                                                                        This breaks for array=('first item' 'second item').

                                                                                        – Benjamin W.
                                                                                        Jun 14 '16 at 17:17







                                                                                      1




                                                                                      1





                                                                                      This breaks for array=('first item' 'second item').

                                                                                      – Benjamin W.
                                                                                      Jun 14 '16 at 17:17





                                                                                      This breaks for array=('first item' 'second item').

                                                                                      – Benjamin W.
                                                                                      Jun 14 '16 at 17:17











                                                                                      -1














                                                                                      This is a quick-and-dirty solution that will work in simple cases but will break if (a) there are regex special characters in $delete, or (b) there are any spaces at all in any items. Starting with:



                                                                                      array+=(pluto)
                                                                                      array+=(pippo)
                                                                                      delete=(pluto)


                                                                                      Delete all entries exactly matching $delete:



                                                                                      array=(`echo $array | fmt -1 | grep -v "^$delete$" | fmt -999999`)


                                                                                      resulting in
                                                                                      echo $array -> pippo, and making sure it's an array:
                                                                                      echo $array[1] -> pippo



                                                                                      fmt is a little obscure: fmt -1 wraps at the first column (to put each item on its own line. That's where the problem arises with items in spaces.) fmt -999999 unwraps it back to one line, putting back the spaces between items. There are other ways to do that, such as xargs.



                                                                                      Addendum: If you want to delete just the first match, use sed, as described here:



                                                                                      array=(`echo $array | fmt -1 | sed "0,/^$delete$///d;" | fmt -999999`)





                                                                                      share|improve this answer































                                                                                        -1














                                                                                        This is a quick-and-dirty solution that will work in simple cases but will break if (a) there are regex special characters in $delete, or (b) there are any spaces at all in any items. Starting with:



                                                                                        array+=(pluto)
                                                                                        array+=(pippo)
                                                                                        delete=(pluto)


                                                                                        Delete all entries exactly matching $delete:



                                                                                        array=(`echo $array | fmt -1 | grep -v "^$delete$" | fmt -999999`)


                                                                                        resulting in
                                                                                        echo $array -> pippo, and making sure it's an array:
                                                                                        echo $array[1] -> pippo



                                                                                        fmt is a little obscure: fmt -1 wraps at the first column (to put each item on its own line. That's where the problem arises with items in spaces.) fmt -999999 unwraps it back to one line, putting back the spaces between items. There are other ways to do that, such as xargs.



                                                                                        Addendum: If you want to delete just the first match, use sed, as described here:



                                                                                        array=(`echo $array | fmt -1 | sed "0,/^$delete$///d;" | fmt -999999`)





                                                                                        share|improve this answer





























                                                                                          -1












                                                                                          -1








                                                                                          -1







                                                                                          This is a quick-and-dirty solution that will work in simple cases but will break if (a) there are regex special characters in $delete, or (b) there are any spaces at all in any items. Starting with:



                                                                                          array+=(pluto)
                                                                                          array+=(pippo)
                                                                                          delete=(pluto)


                                                                                          Delete all entries exactly matching $delete:



                                                                                          array=(`echo $array | fmt -1 | grep -v "^$delete$" | fmt -999999`)


                                                                                          resulting in
                                                                                          echo $array -> pippo, and making sure it's an array:
                                                                                          echo $array[1] -> pippo



                                                                                          fmt is a little obscure: fmt -1 wraps at the first column (to put each item on its own line. That's where the problem arises with items in spaces.) fmt -999999 unwraps it back to one line, putting back the spaces between items. There are other ways to do that, such as xargs.



                                                                                          Addendum: If you want to delete just the first match, use sed, as described here:



                                                                                          array=(`echo $array | fmt -1 | sed "0,/^$delete$///d;" | fmt -999999`)





                                                                                          share|improve this answer















                                                                                          This is a quick-and-dirty solution that will work in simple cases but will break if (a) there are regex special characters in $delete, or (b) there are any spaces at all in any items. Starting with:



                                                                                          array+=(pluto)
                                                                                          array+=(pippo)
                                                                                          delete=(pluto)


                                                                                          Delete all entries exactly matching $delete:



                                                                                          array=(`echo $array | fmt -1 | grep -v "^$delete$" | fmt -999999`)


                                                                                          resulting in
                                                                                          echo $array -> pippo, and making sure it's an array:
                                                                                          echo $array[1] -> pippo



                                                                                          fmt is a little obscure: fmt -1 wraps at the first column (to put each item on its own line. That's where the problem arises with items in spaces.) fmt -999999 unwraps it back to one line, putting back the spaces between items. There are other ways to do that, such as xargs.



                                                                                          Addendum: If you want to delete just the first match, use sed, as described here:



                                                                                          array=(`echo $array | fmt -1 | sed "0,/^$delete$///d;" | fmt -999999`)






                                                                                          share|improve this answer














                                                                                          share|improve this answer



                                                                                          share|improve this answer








                                                                                          edited Nov 1 '16 at 14:44

























                                                                                          answered Nov 1 '16 at 14:16









                                                                                          Joshua GoldbergJoshua Goldberg

                                                                                          2,90919 silver badges35 bronze badges




                                                                                          2,90919 silver badges35 bronze badges
























                                                                                              -1














                                                                                              How about something like:



                                                                                              array=(one two three)
                                                                                              array_t=" $array[@] "
                                                                                              delete=one
                                                                                              array=($array_t// $delete / )
                                                                                              unset array_t





                                                                                              share|improve this answer





























                                                                                                -1














                                                                                                How about something like:



                                                                                                array=(one two three)
                                                                                                array_t=" $array[@] "
                                                                                                delete=one
                                                                                                array=($array_t// $delete / )
                                                                                                unset array_t





                                                                                                share|improve this answer



























                                                                                                  -1












                                                                                                  -1








                                                                                                  -1







                                                                                                  How about something like:



                                                                                                  array=(one two three)
                                                                                                  array_t=" $array[@] "
                                                                                                  delete=one
                                                                                                  array=($array_t// $delete / )
                                                                                                  unset array_t





                                                                                                  share|improve this answer













                                                                                                  How about something like:



                                                                                                  array=(one two three)
                                                                                                  array_t=" $array[@] "
                                                                                                  delete=one
                                                                                                  array=($array_t// $delete / )
                                                                                                  unset array_t






                                                                                                  share|improve this answer












                                                                                                  share|improve this answer



                                                                                                  share|improve this answer










                                                                                                  answered Jun 28 '17 at 0:11









                                                                                                  user8223227user8223227

                                                                                                  1




                                                                                                  1
























                                                                                                      -2














                                                                                                      #/bin/bash

                                                                                                      echo "# define array with six elements"
                                                                                                      arr=(zero one two three 'four 4' five)

                                                                                                      echo "# unset by index: 0"
                                                                                                      unset -v 'arr[0]'
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      arr_delete_by_content() # value to delete
                                                                                                      for i in $!arr[*]; do
                                                                                                      [ "$arr[$i]" = "$1" ] && unset -v 'arr[$i]'
                                                                                                      done


                                                                                                      echo "# unset in global variable where value: three"
                                                                                                      arr_delete_by_content three
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      echo "# rearrange indices"
                                                                                                      arr=( "$arr[@]" )
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      delete_value() sed 's,^[^=]*=,,'


                                                                                                      echo "# new array without value: two"
                                                                                                      declare -a arr="$(delete_value two "$arr[@]")"
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      delete_values() # arraydecl values..., returns array decl. (keeps indices)
                                                                                                      declare -a arr="$1"; local i v; shift
                                                                                                      for v in "$@"; do
                                                                                                      for i in $!arr[*]; do
                                                                                                      [ "$v" = "$arr[$i]" ] && unset -v 'arr[$i]'
                                                                                                      done
                                                                                                      done
                                                                                                      declare -p arr
                                                                                                      echo "# new array without values: one five (keep indices)"
                                                                                                      declare -a arr="$(delete_values "$(declare -p arr|sed 's,^[^=]*=,,')" one five)"
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      # new array without multiple values and rearranged indices is left to the reader





                                                                                                      share|improve this answer




















                                                                                                      • 1





                                                                                                        Can you add some comments or a description to tell us about your answer?

                                                                                                        – Michael
                                                                                                        Oct 17 '17 at 19:26















                                                                                                      -2














                                                                                                      #/bin/bash

                                                                                                      echo "# define array with six elements"
                                                                                                      arr=(zero one two three 'four 4' five)

                                                                                                      echo "# unset by index: 0"
                                                                                                      unset -v 'arr[0]'
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      arr_delete_by_content() # value to delete
                                                                                                      for i in $!arr[*]; do
                                                                                                      [ "$arr[$i]" = "$1" ] && unset -v 'arr[$i]'
                                                                                                      done


                                                                                                      echo "# unset in global variable where value: three"
                                                                                                      arr_delete_by_content three
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      echo "# rearrange indices"
                                                                                                      arr=( "$arr[@]" )
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      delete_value() sed 's,^[^=]*=,,'


                                                                                                      echo "# new array without value: two"
                                                                                                      declare -a arr="$(delete_value two "$arr[@]")"
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      delete_values() # arraydecl values..., returns array decl. (keeps indices)
                                                                                                      declare -a arr="$1"; local i v; shift
                                                                                                      for v in "$@"; do
                                                                                                      for i in $!arr[*]; do
                                                                                                      [ "$v" = "$arr[$i]" ] && unset -v 'arr[$i]'
                                                                                                      done
                                                                                                      done
                                                                                                      declare -p arr
                                                                                                      echo "# new array without values: one five (keep indices)"
                                                                                                      declare -a arr="$(delete_values "$(declare -p arr|sed 's,^[^=]*=,,')" one five)"
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      # new array without multiple values and rearranged indices is left to the reader





                                                                                                      share|improve this answer




















                                                                                                      • 1





                                                                                                        Can you add some comments or a description to tell us about your answer?

                                                                                                        – Michael
                                                                                                        Oct 17 '17 at 19:26













                                                                                                      -2












                                                                                                      -2








                                                                                                      -2







                                                                                                      #/bin/bash

                                                                                                      echo "# define array with six elements"
                                                                                                      arr=(zero one two three 'four 4' five)

                                                                                                      echo "# unset by index: 0"
                                                                                                      unset -v 'arr[0]'
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      arr_delete_by_content() # value to delete
                                                                                                      for i in $!arr[*]; do
                                                                                                      [ "$arr[$i]" = "$1" ] && unset -v 'arr[$i]'
                                                                                                      done


                                                                                                      echo "# unset in global variable where value: three"
                                                                                                      arr_delete_by_content three
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      echo "# rearrange indices"
                                                                                                      arr=( "$arr[@]" )
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      delete_value() sed 's,^[^=]*=,,'


                                                                                                      echo "# new array without value: two"
                                                                                                      declare -a arr="$(delete_value two "$arr[@]")"
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      delete_values() # arraydecl values..., returns array decl. (keeps indices)
                                                                                                      declare -a arr="$1"; local i v; shift
                                                                                                      for v in "$@"; do
                                                                                                      for i in $!arr[*]; do
                                                                                                      [ "$v" = "$arr[$i]" ] && unset -v 'arr[$i]'
                                                                                                      done
                                                                                                      done
                                                                                                      declare -p arr
                                                                                                      echo "# new array without values: one five (keep indices)"
                                                                                                      declare -a arr="$(delete_values "$(declare -p arr|sed 's,^[^=]*=,,')" one five)"
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      # new array without multiple values and rearranged indices is left to the reader





                                                                                                      share|improve this answer













                                                                                                      #/bin/bash

                                                                                                      echo "# define array with six elements"
                                                                                                      arr=(zero one two three 'four 4' five)

                                                                                                      echo "# unset by index: 0"
                                                                                                      unset -v 'arr[0]'
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      arr_delete_by_content() # value to delete
                                                                                                      for i in $!arr[*]; do
                                                                                                      [ "$arr[$i]" = "$1" ] && unset -v 'arr[$i]'
                                                                                                      done


                                                                                                      echo "# unset in global variable where value: three"
                                                                                                      arr_delete_by_content three
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      echo "# rearrange indices"
                                                                                                      arr=( "$arr[@]" )
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      delete_value() sed 's,^[^=]*=,,'


                                                                                                      echo "# new array without value: two"
                                                                                                      declare -a arr="$(delete_value two "$arr[@]")"
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      delete_values() # arraydecl values..., returns array decl. (keeps indices)
                                                                                                      declare -a arr="$1"; local i v; shift
                                                                                                      for v in "$@"; do
                                                                                                      for i in $!arr[*]; do
                                                                                                      [ "$v" = "$arr[$i]" ] && unset -v 'arr[$i]'
                                                                                                      done
                                                                                                      done
                                                                                                      declare -p arr
                                                                                                      echo "# new array without values: one five (keep indices)"
                                                                                                      declare -a arr="$(delete_values "$(declare -p arr|sed 's,^[^=]*=,,')" one five)"
                                                                                                      for i in $!arr[*]; do echo "arr[$i]=$arr[$i]"; done

                                                                                                      # new array without multiple values and rearranged indices is left to the reader






                                                                                                      share|improve this answer












                                                                                                      share|improve this answer



                                                                                                      share|improve this answer










                                                                                                      answered Oct 17 '17 at 19:16









                                                                                                      Gombok ArthurGombok Arthur

                                                                                                      1




                                                                                                      1










                                                                                                      • 1





                                                                                                        Can you add some comments or a description to tell us about your answer?

                                                                                                        – Michael
                                                                                                        Oct 17 '17 at 19:26












                                                                                                      • 1





                                                                                                        Can you add some comments or a description to tell us about your answer?

                                                                                                        – Michael
                                                                                                        Oct 17 '17 at 19:26







                                                                                                      1




                                                                                                      1





                                                                                                      Can you add some comments or a description to tell us about your answer?

                                                                                                      – Michael
                                                                                                      Oct 17 '17 at 19:26





                                                                                                      Can you add some comments or a description to tell us about your answer?

                                                                                                      – Michael
                                                                                                      Oct 17 '17 at 19:26





                                                                                                      protected by codeforester Sep 15 '18 at 1:16



                                                                                                      Thank you for your interest in this question.
                                                                                                      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                                                                                      Would you like to answer one of these unanswered questions instead?



                                                                                                      Popular posts from this blog

                                                                                                      Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                                                                                                      Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                                                                                                      Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript