15

Help for a simple script

#!/bin/bash

array1=(
prova1
prova2
slack64
)

a="slack64"
b="ab"

if [ $a = $b ]
then
      echo "$a = $b : a is equal to b"
else
      echo "$a = $b: a is not equal to b"
fi

This script simply doesn't work, I want a script which check if slack64 is present in a list(i use an array),and simply give me, yes is present,or no. I don't know how to compare an array with a single variable.

  • 4
    Where does the array1 work? – tachomi Jan 3 '15 at 3:38
17

Use a different kind of array: rather than an integer-indexed array, use an associative array, so the key (index) is what you will be checking for. bash-4.0 or later is required for this.

declare -A array1=( 
 [prova1]=1  [prova2]=1  [slack64]=1
)

a=slack64
[[ -n "${array1[$a]}" ]] && printf '%s is in array\n' "$a"

In the above we don't really care about the values, they need only be non-empty for this. You can "invert" an indexed array into a new associative array by exchanging the key and value:

declare -a array1=( 
 prova1 prova2 slack64
)
declare -A map    # required: declare explicit associative array
for key in "${!array1[@]}"; do map[${array1[$key]}]="$key"; done  # see below

a=slack64
[[ -n "${map[$a]}" ]] && printf '%s is in array\n' "$a"

This can pay off if you have large arrays which are frequently searched, since the implementation of associative arrays will perform better than array-traversing loops. It won't suit every use case though, since it cannot handle duplicates (though you can use the value as a counter, instead of just 1 as above), and it cannot handle an empty index.

Breaking out the complex line above, to explain the "inversion":

for key in "${!a[@]}"     # expand the array indexes to a list of words
do 
  map[${a[$key]}]="$key"  # exchange the value ${a[$key]} with the index $key
done
14

The straightforward way is to iterate with a loop :

var=ab
for item in "${array[@]}"; do
    [[ $var == "$item" ]] && echo "$var present in the array"
done
  • ? [[ a == aaa ]] is false but a match aaa no ? – Gilles Quenot Jan 4 '15 at 23:53
  • SO the OP should be informed that he have to take care if the values can contain special characters, like [ ] : character class (globs) – Gilles Quenot Jan 5 '15 at 11:15
  • I see no difference between = and == in bash [[ ]] for what you said. Have you tested ? – Gilles Quenot Jan 5 '15 at 11:59
2

With zsh:

array1=(
  prova1
  prova2
  slack64
)

a=slack64

if ((array1[(Ie)$a])); then
  printf '%s\n' "$a in array1"
fi
2

This function works with associative arrays.

We can use this function to do one of the following:

-- check if the array has a certain key -----------------> inArray "myKey" ${!myArray[@]}"

-- check if the array contains a certain value ---------> inArray "myValue" "${myArray[@]}"

function inArray # ( keyOrValue, arrayKeysOrValues ) 
{
  local e
  for e in "${@:2}"; do 
    [[ "$e" == "$1" ]] && return 0; 
  done
  return 1
}

declare -A arr
arr[doo]=55

inArray "doo" "${!arr[@]}"
echo $?     # 0 
inArray "bla" "${!arr[@]}"
echo $?     # 1 
inArray "55" "${arr[@]}"
echo $?     # 0
1

You can also use grep for that:

array1=(prova1 prova2 slack64)
a=slack64
if (printf '%s\n' "${array1[@]}" | grep -xq $a); then
    echo "it's in"
fi
  • 1
    That assumes the array elements don't contain newline characters (and blanks and wildcards as you forgot to quote $a, and don't start with - as you forgot the --). You could use %s\0 instead of %s\n and use grep --null (assuming GNU grep or compatible) as bash variables can't contain the NUL character anyway. You'd also need to handle the case of an empty array specially (as that printf command would print the same thing as for an array with one empty element). Also note that you don't need to start a subshell here. – Stéphane Chazelas Nov 9 '17 at 16:58
  • yes, it is applicable on the simple arrays like the one in the question. – Petr Ketner Nov 10 '17 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.