0

This question already has an answer here:

What I'm trying to do is the get the user input and search through the file, If it match it will show the result, else it will echo $keyword not found.

But my scrip is always return fault.

       read -p "Enter keyword: " keyword
       if search="$(cat ./records | grep '$keyword')"
       then
       echo "$search"
       else
        echo "$keyword not found!"
       fi ;;

marked as duplicate by jasonwryan, Community Sep 27 '17 at 6:39

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • the error is that you are using '$keyword'. within single quotes the variable is not expanded and treated as text. use "$keyword" instead. – John Smith Sep 27 '17 at 6:40
1
read -r -p 'Enter pattern: ' pattern

result=$( grep "$pattern" records )

if [ -n "$result" ]; then
    printf '%s\n' "$result"
else
    printf 'No match found for pattern "%s"\n' "$pattern"
fi
  • The assignment to search (result in my code) is best done outside of the if statement.

  • Test with -n ("is this string non-empty?") on the result.

  • Don't single-quote the variable (it will prevent the shell from expanding its value). Double quote it instead.

  • Notice "pattern" rather than "keyword". The way you use grep here will use the user-supplied string as a regular expression (a pattern, such as cat.*dog), not necessarily as a plain fixed string.

  • cat should be used to concatenate files, in most other cases it's more or less useless.

  • Use read -r to allow the user to enter backslashes.


Alternatively:

read -r -p 'Enter pattern: ' pattern

if grep "$pattern" records; then
    true
else
    printf 'No match found for pattern "%s"\n' "$pattern"
fi

This avoids storing a potentially huge amount of data in a shell variable and instead relies on the exit status of grep to tell whether the pattern may be found in the file or not. If the pattern is found, the matching lines will be printed (and nothing more has to be done, thus the true statement).

Regarding the use of printf in place of echo: Why is printf better than echo?


Shorter:

read -r -p 'Enter pattern: '

grep "$REPLY" records || printf 'No match found for pattern "%s"\n' "$REPLY"
  • I would replace if grep -q by if grep, and replace second grep by true. – Archemar Sep 27 '17 at 6:34
  • @Archemar Doubleplusgood – Kusalananda Sep 27 '17 at 6:36
  • Thanks so much for your help, It works ! I learn something new !!! – Prin Puyakul Sep 27 '17 at 6:38
  • on side note alternative is useful only if you don't intend to reuse grep's result. – Archemar Sep 27 '17 at 6:41
  • @Archemar If you want to use the result of grep it is often the case that you should write it in awk instead :-) – Kusalananda Sep 27 '17 at 6:43
1

See below:

read -p "Enter keyword: " keyword

if search=$(grep "$keyword" ./records)
        then
                echo "$search"
        else
                echo "$keyword not found!"
        fi
  1. Don't use quotting with $() as @jasonwryan was noted above
  2. Not nesessary to use cat piping with grep. Use grep <pattern> file instead
  3. Delete ;; after fi
  • Thanks so much you solution is working too!! ";;" cos its in my Switch case but thanks for point it out ^^" – Prin Puyakul Sep 27 '17 at 6:38

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