4

Imagine we have an array like this:

declare -a array=( "one" "two" "three" "four" "five" )

for i in "${all[@]}"; do
        echo "$i"
done

And we can give an input from the user like this:

read -p "Enter a number: " number

I need something to check if the user input matches one of the elements of this array. If not, this should run:

echo "Try again: " 

This process should be repeated until the user input matches to one of the array elements.

  • Is this a homework project? – Graham Oct 1 at 16:50
  • No. I just tried many ways but as I'm new learner I did not find a good way. – msndm Oct 1 at 16:53
  • 3
    this reads very similar to a homwork problem... What have you tried so far? Have you gotten any errors? Or are you just asking for a handout? – j-money Oct 1 at 16:54
  • 1
    stackexchange.com/filters/169 might be a better place for this question if its not about Ubuntu. – Graham Oct 1 at 16:55
  • 1
    This question is perfectly on-topic here. Please do not close questions as off-topic just because they're about bash. We have a lot of users who are able to help with Bash questions. I would even argue that these questions would be better received here on Ask Ubuntu and on Unix & Linux! – Dan Oct 2 at 11:27
3

You do not need to loop over the array to check whether a value belongs to it. Also, in this case I would use a recursive call of a function instead of another loop. As I understand correctly you are searching for something like this:

#!/bin/bash

array=( "one" "two" "three" "four" "five" )

function get_input() {
    read -p "${1}: " number
    if [[ " ${array[*]} " == *" ${number} "* ]]
    then
        echo 'true';
    else
        get_input 'Try again'   # a recursive call of the function
    fi
}

get_input 'Enter a number'      # the initial call of the function

With the [[ test command we searing for exact match == between one string (the left side) and one regular expression (the right side).

  • The expression " ${array[*]} " will expand our array as a string, surrounded by two spaces, thus each element (even the first and the last) will be surrounded by spaces - try echo '^'" ${array[*]} "'$'.

  • The regular expression *" ${number} "* will match to any strung that consist of the value of the variable $number, surrounded by spaces, surrounded by no mater what other characters *.

We can perform such test by some other tools like grep (with suppressed stdout -q, and searching for exact match \<...\>). Here is one funny version:

#!/bin/bash

array=( "one" "two" "three" "four" "five" )

function get_input() {
    read -p "${1}: " nm
    echo "${array[*]}" | grep -q "\<${nm}\>" && echo 'true' || get_input 'Try again'
}

get_input "Enter a number"

If we want to call the corresponding number of each element in the array instead of inserting the words like ''one'' or ''two'', what can we do? for example: Enter the number: 2

#!/bin/bash

array=( "one" "two" "three" "four" "five" )

# Get the lenght of the array
array_lenght="${#array[*]}"

function get_input() {
    read -p "${1}: " number

    # Test whether the variable $number has a value &and&
    # test whether as integer this value is less or equal to the $array_lenght
    if [[ ! -z ${number} ]] && (( number <= array_lenght && number > 0 ))
    then
        # Outpit the value of the cerain array element
        # Note the first array element has number 0
        echo "${array[$(( number - 1 ))]}"
    else
        get_input 'Try again'
    fi
}

get_input 'Enter an integer number'
  • 1
    this will get you a clear look [[ " ${array[*]} " =~ " ${number} " ]] – bac0n Oct 2 at 7:17
  • If we want to call the corresponding number of each element in the array instead of inserting the words like ''one'' or ''two'', what can we do? for example: Enter the number: 2 – msndm Oct 3 at 16:48
  • Hi, @msndm, the question is updated. – pa4080 Oct 3 at 19:00
5

You can make the array into an associative array instead.

#!/bin/bash

declare -A array=([one]=1 [two]=1 [tree]=1 [four]=1 [five]=1)

m="Guess? "

while true; do   
    read -r -p "$m" i
    [[ ${array[$i]} == 1 ]] && break || m="Guess again? "
done  

echo "Good guess!"
3

Probably all the other answers are more efficient than this one, but I think that this is more beginner-friendly:

declare -a all=( "one" "two" "three" "four" "five" )

read -p "Enter a number: " number

while true; do

    for i in "${all[@]}"; do
        if [[ "$number" = "$i" ]]; then
            exit 0
        fi
    done

    read -p "Try again: " number

done
2
#!/bin/bash

declare -a array=("one" "two" "three" "four" "five")

number="wrong"

while [[ ! "${array[@]}" =~ "${number}" ]]; do
  [[ "${number}" != "wrong" ]] && echo "Incorrect"
  read -p "Insert number: " number
done

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.