0
#!/bin/bash

echo 'Please enter the name of the species you are looking for: '

read speciesName

grep "$speciesName" speciesDetails.txt | awk '{print $0}'
echo
echo 'Would you like to search for another species? Press y to search or n to go back 
to the main menu: ' 
read answer

case $answer in
[yY] | [yY][eE][sS] )
    ./searchSpecies.sh;;
[nN] | [nN][oO] )
    ./speciesMenu.sh;;
*) echo exit;;
esac

If there is no entry of that species name in the file how do I give the user an error to say not found?

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 1
    The pipe to Awk seems like a no-op. If your real code does something actually useful with Awk, probably [factor out the `grep`.](https://www.iki.fi/era/unix/award.html#grep) – tripleee Oct 10 '21 at 12:03

2 Answers2

3

The answer to your immediate question is to examine the exit code from grep. But probably also refactor the loop:

#!/bin/bash

while true; do
    read -p 'Please enter the name of the species you are looking for: ' -r speciesName
    grep -e "$speciesName" speciesDetails.txt || echo "$speciesName: not found" >&2

    read -p 'Would you like to search for another species? Press n to quit: ' -r answer
    case $answer in
     [nN] | [nN][oO] )
        break;;
    esac
done

A better design altogether is probably to make the search term a command-line argument. This makes the script easier to use from other scripts, and the user can use the shell's facilities for history, completion, etc to run it as many times as they like, and easily fix e.g. typos by recalling the previous invocation and editing it.

#!/bin/bash
grep -e "$1" speciesDetails.txt || echo "$1: not found" >&2

The short-circuit one || two corresponds to the longhand

if one; then
    : nothing
else
    two
fi

If you want to search for static strings, not regular expressions, maybe add -F to the grep options.

tripleee
  • 175,061
  • 34
  • 275
  • 318
0

If you need just check existance then execute it using next way :

if grep speciesName4 speciesDetails.txt; then
   echo "exist";  
else 
   echo "Not exist"; 
fi

Use $? to check exit code of the command if you need return value as well

set -o pipefail
$ echo "speciesName1" > speciesDetails.txt
$ echo "speciesName2" >> speciesDetails.txt
$ echo "speciesName3" >> speciesDetails.txt

$ l_result=$(grep speciesName3 speciesDetails.txt); l_exit_code=$?
$ echo $l_exit_code
0

$ l_result=$(grep speciesName4 speciesDetails.txt); l_exit_code=$?
$ echo $l_exit_code
1

Updated:

It is not antipattern if you need to use later output of your command

Arkon88
  • 180
  • 5
  • 1
    No, don't. [Why is testing ”$?” to see if a command succeeded or not, an anti-pattern?](https://stackoverflow.com/questions/36313216/why-is-testing-to-see-if-a-command-succeeded-or-not-an-anti-pattern) – tripleee Oct 10 '21 at 12:02
  • thanks, improved my answer, added more details – Arkon88 Oct 10 '21 at 13:42