开发者

Bash Select position of array element by args

I want make a bash script which returns the position of an element from an array by give an arg. See code below, I use:

#!/bin/bash
args=("$@")
echo ${args[0]}
test_array=('AA' 'BB' 'CC' 'DD' 'EE')
echo $test_array
elem_array=${#test_array[@]}
for args in $test_array
do
        echo 
done

Finally I should have output like:

$script.sh 开发者_开发技巧DD
4


#!/bin/bash

A=(AA BB CC DD EE)

for i in "${!A[@]}"; do
        if [[ "${A[i]}" = "$1" ]]; then
                echo "$i"
        fi
done

Note the "${!A[@]}" notation that gives the list of valid indexes in the array. In general you cannot just go from 0 to "${#A[@]}" - 1, because the indexes are not necessarily contiguous. There can be gaps in the index range if there were gaps in the array element assignments or if some elements have been unset.

The script above will output all indexes of the array for which its content is equal to the first command line argument of the script.

EDIT:

In your question, you seem to want the result as a one-based array index. In that case you can just increment the result by one:

#!/bin/bash

A=(AA BB CC DD EE)

for i in "${!A[@]}"; do
        if [[ "${A[i]}" = "$1" ]]; then
                let i++;

                echo "$i"
        fi
done

Keep in mind, though, that this index will have to be decremented before being used with a zero-based array.


Trying to avoid complex tools:

test_array=('AA' 'BB' 'CC' 'D D' 'EE')
OLD_IFS="$IFS"
IFS="
"
element=$(grep -n '^D D$' <<< "${test_array[*]}" | cut -d ":" -f 1)
IFS="$OLD_IFS"
echo $element

However, it consumes 2 processes. If we allow ourselves sed, we could do it with a single process:

test_array=('AA' 'BB' 'CC' 'D D' 'EE')
OLD_IFS="$IFS"
IFS="
"
element=$(sed -n -e '/^D D$/=' <<< "${test_array[*]}")
IFS="$OLD_IFS"
echo $element

Update:

As pointed out by thkala in the comments, this solution is broken in 3 cases. Be careful not to use it if:

  1. You want zero indexed offset.
  2. You have newlines in your array elements.
  3. And you have a sparse array, or have other keys than integers.


Loop over the array and keep track of the position. When you find the element matching the input argument, print out the position of the element. You need to add one to the position, because arrays have zero-based indexing.

#! /bin/sh
arg=$1
echo $arg
test_array=('AA' 'BB' 'CC' 'DD' 'EE')
element_count=${#test_array[@]}
index=0

while [ $index -lt $element_count ]
do    
  if [ "${test_array[index]}" = "$arg" ]
  then
     echo $((index+1))
     break
  fi
  ((index++))
done


Without loop:

#!/bin/bash

index() {
    local IFS=$'\n';
    echo "${*:2}" | awk '$0 == "'"${1//\"/\\\"}"'" { print NR-1; exit; }'
}

array=("D A D" "A D" bBb "D WW" D "\" D \"" e1e " D " E1E D AA "" BB)
element=${array[5]}
index "$element" "${array[@]}"

Output:

5
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜