4

I am using if-else statement to search for keywords and displaying the results in the terminal, here's an example of my code.

read finding

if ["$finding" != "" ]; then
   grep $finding information.txt
else
   echo "No such information in database."
fi

But the terminal does not display anything if i key in information that does not exist. I started shell about a week back, might need more explanation on how certain code works.

6
  • This and @jimmij's code do not display “No such information in database.” when the information is not in the data-base, but when you input no information. (It will grep or echo the error message.) Jan 12, 2015 at 21:31
  • Yes, do you know what is causing this error ? @richard
    – Zac
    Jan 13, 2015 at 4:30
  • look at the code. It does the conditional (if), then does the grep or it does the echo "no such information in database". The echo is not a reaction to grep. If is pre determined before grep is (not) run. Jan 15, 2015 at 22:44
  • -1 for posting code, that is not the code exhibiting the error you describe. (please edit question to show us the code you where having problems with.) Jan 15, 2015 at 22:46
  • nope, if i place my code here, it wouldn't make any sense at all, hence i created a small example to let you guys understand, no need to -1, please +1 again. @richard
    – Zac
    Jan 16, 2015 at 20:14

3 Answers 3

5
  • Add space after [ (it is a command)
  • Use -n to test if length of string is nonzero, or -z to test if it is zero
  • Put double quotes around variables

So:

read finding

if [ -z "$finding" ]; then
    echo "You didn't enter anything"
else
    grep "$finding" information.txt
    if [ ! "$?" -eq 0 ]; then
        echo "No such information in database."
    fi
fi
9
  • sorry, but what do you mean by non zero and zero
    – Zac
    Jan 12, 2015 at 19:18
  • I mean that instead of "$finding" != "" you should use -n "$finding". This is standard procedure to test that "there is something" in the variable. See man test to read what other options you can use with test (or []).
    – jimmij
    Jan 12, 2015 at 19:22
  • tried it, but my code current have 2 conditions in if For exmaple: if [ "$name" != "$blank" ] && [ "$age" = "$blank" ]; then echo true fi I changed it to if [ -n "$name" ] && [ -n "$age" ]; then echo true fi I encountered logic error whereby it would jump straight to else instead.
    – Zac
    Jan 12, 2015 at 19:33
  • If "name" must not be blank, and "age" must, then it should be [ -n "$name" ] && [ -z "$age" ]
    – jimmij
    Jan 12, 2015 at 19:42
  • Thanks for putting in the extra effort to explain, managed to simplified my code, but it's still not displaying the else part, I have already added blanks way before, forgot to add blanks for my question here.
    – Zac
    Jan 12, 2015 at 19:47
4

Using some logic operators (Starting from @jimmij)

grep -q "$finding" information.txt behaves like a boolean answer (prints nothing just has a return status of 0 if found, non-zero otherwise).

grep -F -- "$finding" ... search text instead of regexp (remove it if you want to search for regexp -- there may be some security risks... (thank you @StephanChazelas))

read finding

if [ -z "$finding" ]; then
   echo "You didn't enter anything"
else
   grep -qF -- "$finding" information.txt   && echo "found"   || echo "not found"
fi

or even

[ -z "$finding" ] && 
     echo "nothing entered" || 
     grep -qF -- "$finding" information.txt || echo "not found"

(though beware it will also run the second grep and/or echo if the first echo fails)

Edit 1 > explain grep -q ... Sure.

In normal situations, grep return status is 0 (and just returns "not 0" if an error occurs (eg. file not found))

grep -qF exp file "returns" 0 if it finds exp in file, error otherwise (grep -q exp file would do that if the exp regexp was matched in file).

This behavior can be used in bash control statements (if,elif, while, &&, ||,etc)

read f

if [ -z "$f" ]; then
   echo "You didn't enter anything"
elif grep -qF -- "$f" information.txt; then
   echo "found"
else
   echo "not found"
fi
2
  • do you mind explaining how does -q work in your example ?
    – Zac
    Jan 13, 2015 at 14:12
  • @zac, please see if this edit helps...
    – JJoao
    Jan 13, 2015 at 14:52
0
i=0
until  [ "$((i+=1))" -gt 5 ] || {
       printf '\nPrompt: '
       read finding && [ -n "$finding" ]
};do   printf '\nINVALID:\tTry again.\n'
done   <>/dev/tty >&0
grep -- "${finding:?INSUFFICIENT INPUT!}" <info.txt ||
! printf '%s:\tNot found in database.' "$finding" >&2

You should be testing not only that $finding is not null, but also that the read is completing successfully - and so setting it in the first place. The above loop will prompt on and attempt to read from the terminal a line of not-null input input 5 times before quitting w/ error.

  • "${expand:?SUBSTITUTE ONLY IF UNSET OR NULL! >STDERR}"
    • An empty value for $finding is handled as a side effect of the ${parameter:?expansion} and results in a message written to stderr and the immediate exit of a non-interactive shell.
  • cmd ... <redirected_input_file
    • It is a syntax error to attempt to redirect from a file which cannot be opened (such as one which does not exist or for which the effective UID/GID does not have read permissions) and so if info.txt is for whatever reason invalid a non-interactive shell writes a diagnostic message to stderr and also exits immediately. This also holds true if the attempted read exceeds any limitations as effected by ulimit - and applies equally for the initial until ... done <>in >&out loop.
  • grep ... || ! printf '%s: fmt' "$param"
    • Because any user or file input errors have already resulted in a shell exit before grep is called, the only two other possible results of the above form are that grep matches the pattern in "$finding" at least once and writes the corresponding lines to stdout or that it does not match even once and returns other than 0. In the latter case printf writes an informative message to stderr and returns 1.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .