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:
- You want zero indexed offset.
- You have newlines in your array elements.
- 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
精彩评论