5

My script is setting array from grep results in such a way that empty grep results are also being stored in array.

Eg.

set -x echo "${Arr[@]}" + echo '' 'word' '' 'word2' 

Can someone help unset those empty values so that echo "${#Arr[@]}" gives 2 instead of 4

Tried

var=-1 && for i in "${Input_Arr[@]}"; do var=$((var+1)); if [ -z "$i" ]; then unset "${Input_Arr[$var]}"; fi; done 

But it isn't working

    2 Answers 2

    7

    First, there's no need to invent a dummy index - you can access the array's indices using the indirection operator !

    Second, "${Input_Arr[$var]}" is the element's value; unset needs the element's name, Input_Arr[$var] or just Input_Arr[var], since it's already an arithmetic context). So given:

    $ arr=(foo '' bar '' baz) $ declare -p arr declare -a arr=([0]="foo" [1]="" [2]="bar" [3]="" [4]="baz") 

    then

    $ for i in ${!arr[@]}; do [[ -z ${arr[i]} ]] && unset arr[i]; done 

    leaves

    $ declare -p arr declare -a arr=([0]="foo" [2]="bar" [4]="baz") 

    This also works for associative arrays - with suitable adjustments for the non-numeric keys (including double quoting expansions to prevent potential split + glob):

    $ declare -A Arr=(['1st val']=foo ['2nd val']='' ['3rd val']=bar ['4th val']='' ['5th val']=baz) $ declare -p Arr declare -A Arr=(["5th val"]="baz" ["2nd val"]="" ["4th val"]="" ["3rd val"]="bar" ["1st val"]="foo" ) $ for i in "${!Arr[@]}"; do [[ -z ${Arr[$i]} ]] && unset Arr["$i"]; done $ declare -p Arr declare -A Arr=(["5th val"]="baz" ["3rd val"]="bar" ["1st val"]="foo" ) 
      3

      If you want the remaining array elements to be collapsed to consecutive indexes starting from zero, it's probably easiest to make a copy of the array:

      arr1=(foo '' bar '') arr2=() for val in "${arr1[@]}"; do [[ $val ]] && arr2+=( "$val" ) done 

      That would leave arr2 as declare -a arr2=([0]="foo" [1]="bar"), i.e. the index of bar was changed from 2 to 1 to avoid leaving a hole.

      You could also do that in-place by just copying the individual elements and unsetting the last ones, but it's more manual work.

        You must log in to answer this question.

        Start asking to get answers

        Find the answer to your question by asking.

        Ask question

        Explore related questions

        See similar questions with these tags.