Get the index of a value in a Bash array

后端 未结 15 509
说谎
说谎 2021-01-30 03:41

I have something in bash like

myArray=(\'red\' \'orange\' \'green\')

And I would like to do something like

echo ${         


        
相关标签:
15条回答
  • 2021-01-30 04:18

    This might just work for arrays,

    my_array=(red orange green)
    echo "$(printf "%s\n" "${my_array[@]}")" | grep -n '^orange$' | sed 's/:orange//'
    

    Output:

    2
    

    If you want to find header index in a tsv file,

    head -n 1 tsv_filename | sed 's/\t/\n/g' | grep -n '^header_name$' | sed 's/:header_name//g'
    
    0 讨论(0)
  • 2021-01-30 04:18

    This shows some methods for returning an index of an array member. The array uses non-applicable values for the first and last index, to provide an index starting at 1, and to provide limits.

    The while loop is an interesting method for iteration, with cutoff, with the purpose of generating an index for an array value, the body of the loop contains only a colon for null operation. The important part is the iteration of i until a match, or past the possible matches.

    The function indexof() will translate a text value to an index. If a value is unmatched the function returns an error code that can be used in a test to perform error handling. An input value unmatched to the array will exceed the range limits (-gt, -lt) tests.

    There is a test (main code) that loops good/bad values, the first 3 lines are commented out, but try some variations to see interesting results (lines 1,3 or 2,3 or 4). I included some code that considers error conditions, because it can be useful.

    The last line of code invokes function indexof with a known good value "green" which will echo the index value.

    indexof(){
      local s i;
    
      #   0    1   2     3    4
      s=( @@@ red green blue @o@ )
    
      while [ ${s[i++]} != $1 ] && [ $i -lt ${#s[@]} ]; do :; done
    
      [ $i -gt 1 ] && [ $i -lt ${#s[@]} ] || return
    
      let i--
    
      echo $i
    };# end function indexof
    
    # --- main code ---
    echo -e \\033c
    echo 'Testing good and bad variables:'
    for x in @@@ red pot green blue frog bob @o@;
    do
      #v=$(indexof $x) || break
      #v=$(indexof $x) || continue
      #echo $v
      v=$(indexof $x) && echo -e "$x:\t ok" || echo -e "$x:\t unmatched"
    done 
    
    echo -e '\nShow the index of array member green:'
    indexof green
    
    0 讨论(0)
  • 2021-01-30 04:22

    There is also one tricky way:

    echo ${myArray[@]/green//} | cut -d/ -f1 | wc -w | tr -d ' '
    

    And you get 2 Here are references

    0 讨论(0)
  • 2021-01-30 04:22
    myArray=('red' 'orange' 'green')
    echo ${myArray[@]}
    arrayElementToBeRemoved='orange'
    echo "removing element: $arrayElementToBeRemoved"
    # Find index of the array element (to be kept or preserved)
    let "index=(`echo ${myArray[@]} | tr -s " " "\n" | grep -n "$arrayElementToBeRemoved" | cut -d":" -f 1`)-1"
    unset "myArray[$index]"
    echo ${myArray[@]}
    
    0 讨论(0)
  • 2021-01-30 04:22

    I wanted something similar myself and avoiding a loop, came up with ...

    myArray=('red' 'orange' 'green')
    declare -p myArray | sed -n "s,.*\[\([^]]*\)\]=\"green\".*,\1,p"
    

    ... which leaves stdout unsullied should the element not be found...

    $ myArray=('red' 'orange' 'green')
    $ declare -p myArray | sed -n "s,.*\[\([^]]*\)\]=\"green\".*,\1,p"
    2
    
    $ declare -p myArray | sed -n "s,.*\[\([^]]*\)\]=\"gren\".*,\1,p"
    $
    

    After which I googled, found this question and thought I'd share ;)

    0 讨论(0)
  • 2021-01-30 04:22

    Simple solution:

    my_array=(red orange green)
    echo ${my_array[*]} | tr ' ' '\n' | awk '/green/ {print NR-1}'
    
    0 讨论(0)
提交回复
热议问题