Boston Linux & UNIX was originally founded in 1994 as part of The Boston Computer Society. We meet on the third Wednesday of each month at the Massachusetts Institute of Technology, in Building E51.

BLU Discuss list archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

passing arrays and working with arrays in BASH



On Fri, 2010-03-26 at 17:12 -0400, theBlueSage wrote:
> Ho Folks,
> 
> so it has taken me _ages_ to get this to work and Icant believe this is
> the best/only way to get this done :
> 
> Problem : 
> I am writing server install scripts, and BASH is the chosen tool. I
> needed to write a function that could receive an array and a value, and
> then simply return the position in the array if the given value. This is
> seriously easy in something like PHP using in_array($arr, $val), but in
> was a completely different kettle of fish in BASH.
> 
> Solution (that I have working right now, in example form):
> 
> ------------ start code snippet --------------
> 
> #!/bin/bash
> function search_array() {
>     index=0
>     array=( "$@" )
>     #echo ${array[@]}
>     let TCNT=${#array[@]}-1
>     LASTVAL=${array[${#array[@]}-1]}
>     while [ "$index" -lt "$TCNT" ]; do
>         if [ "${array[$index]}" = "$LASTVAL" ]; then
>             echo $index
>             return
>         fi
>         let "index++"
>     done
>     echo ""
> }
> 
> 
> echo -e -n "enter a value to search for : "
> read -e KEY
> arr=( f q e c d s a )
> arr[${#arr[@]}+1]=$KEY
> position=$(search_array "${arr[@]}")
> if [ -z "$position" ]; then
>     echo -e "the value "$KEY" is not in the array"
> else
>     echo -e "the value "$KEY" was found at position: "$position
> fi
> exit 0
> 
> 
> -------- end code snippet ----------------
> 
> where : 'KEY' is the value to search for and 'arr' is the array to
> search in
> 
> 
> I did it this way as I couldn't find any other way to pass an array
> _and_ a scalar value to the function. The result is I add the scalar to
> the end of the array, pass it to the function and then peel it off
> again.
> 
> SURELY there is a better way of doing it than this ?
> 
> thanks for any suggestions
> 
> 
> Richard
> 

Sorry to chime in so late.

Arrays are the wrong abstraction for shell scripts.  Arrays are more or
less a mid-90's bolt-on.

Think lists.  Remember that:

Any value containing spaces is a list.  You can change the definition of
"space" using the special variable IFS.

The variable $* is a special list that acts a little like a stack.  You
can set it with set:

$ set a b c
$ echo $*
a b c
$ shift; echo $*   # pop
b c
$ set a $*         # push
$ echo $*
a b c 

Be careful:

$ X=
$ set $X

will give ugly results.  The most portable workaround looks a little
like this:

$ set xx $X; shift



Um...

$ R=$(grep '^root' /etc/passwd | sed 's/[[:space:]]/_/g')
$ set $(IFS=:;echo $R)
$ echo $*
root x 0 0 root /root /bin/bash
$ echo $6
/root

So....

Send your key as the first arg and the list of items as the remaining
args:

SearchFor() {
  declare K= ITEM="$1"; shift
  declare LIST="$@"
  declare -i N=1

  for K in $LIST; do
    if [ "$K" == "$ITEM" ];then
      echo $N; return 0
    fi
    let N++
  done
  return 1
}


echo -e -n "enter a value to search for : "
read -e KEY
arr="f q e c d s a"
position=$(search_array "$KEY" $arr)
if [ -z "$position" ]; then
    echo -e "the value "$KEY" is not in the array"
else
    echo -e "the value "$KEY" was found at position: "$position
fi
exit 0


I of course did no testing....


HTH
ccb








BLU is a member of BostonUserGroups
BLU is a member of BostonUserGroups
We also thank MIT for the use of their facilities.

Valid HTML 4.01! Valid CSS!



Boston Linux & Unix / webmaster@blu.org