0

I have a shell script with if and elif logic. I am trying to check keyword match with grep command.Whatever keywords I am passing the script is executing last block only.here is my script.

tail -n 0 -F hive-server2.log | \
while read LINE
do
if [ `echo "$LINE" | grep -c "select .*" ` -gt 0 ]
then
  AuditTypeID=15
  QueryResult=$(grep -oEi 'SELECT .*' hive-server2.log | sed -n \$p)
elif [ `echo "$LINE" | grep -c "CREATE" ` -gt 0 ]
then
  AuditTypeID=13
  QueryResult="$(grep -oEi 'CREATE EXTERNAL TABLE [a-zA-Z][a-zA-Z0-9_]*' hive-server2.log | sed -n \$p)"
fi
done

If I pass "select * from table", It is executing elif part only. Even If I pass any query It is executing elif part. Any help would be appreciated.

19
  • Where are you passing arguments to this script? You seem to be tail-ing from a file to read lines Commented Mar 30, 2018 at 5:59
  • 1
    @TejuPriya: Just a side note: The .* in the first grep pattern is redundant. Commented Mar 30, 2018 at 6:20
  • @TejuPriya: In the script you are posting, even the elif part can not be executed. You are writing tail -n 0, which means take the last zero lines from the log file, i.e. nothing is piped into the loop and the first read fails already. If you really observe the behaviour that the elif part is executed, it can't be from this script. BTW, combining the -n and -F option doesn't make sense. Commented Mar 30, 2018 at 6:25
  • 1
    @TeuPriya please show us samples of inputs and outputs in your posts it will be better for us to understand the requirements. Commented Mar 30, 2018 at 6:31
  • Shouldn't the first select be in uppercase? Commented Mar 30, 2018 at 6:36

2 Answers 2

1

Your logic looks very much like you need to discover the case statement.

tail -n 0 -F hive-server2.log |  # No backslash necessary here
tr A-Z a-z |  # Convert to lower case
while read -r line    # -r option; lowercase variable
do
    case $line in
      *'select '*)
          AuditTypeID=15
          QueryResult="$(grep -oEi 'SELECT .*' hive-server2.log | sed -n \$p)";;
       *create*)
          AuditTypeID=13
          QueryResult="$(grep -oEi 'CREATE EXTERNAL TABLE [a-zA-Z][a-zA-Z0-9_]*' hive-server2.log | sed -n \$p)";;
done

The antipattern if [ $(echo "blah" | grep -c something) -gt 0 ] is common but very unidiomatic (see useless use of grep); the way to check if grep matched something is just if echo "blah" | grep -q something but here, you can obviously use the shell's built-in pattern-matching facilities to simplify even further.

Uppercase variable names are reserved for system use; I recommend lower or mixed case for all your script's private variables.

Your code might still have other bugs (rereading the entire file to find the latest create or select statement very much looks like something you should probably refactor) but the immediate problem seems to be that you are matching a lowercase string against an uppercase pattern. The code above folds the input to lower case, which is an easy fix as such, but not always a desirable workaround (perhaps you want to see the original line, not the case-folded version, in the output?). Bash 4.x provides a simple facility for case-folding so you could say case ${line,,} and remove the tr.

Sign up to request clarification or add additional context in comments.

Comments

0

with my simulation, that works with:

tail -n 0 -F hive-server2.log | \
while read line; do
    if [[ "$line" =~ select[[:blank:]]count ]]; then
        echo "action select count"
    elif [[ "$line" =~ select[[:blank:]]\*[[:blank:]]from ]]; then
        echo "action select * from"
    elif [[ "$line" =~ DROP ]]; then
        echo "action drop"
    elif [[ "$line" =~ CREATE ]]; then
        echo "action create"
    fi
done
  • as said tripleee:
    • tail -n 0 -f starts reading the file without seeking back
    • tail -n 1 -f seeks back and prints the last line
  • if you test with an echo, ensure to quote, example:
    echo "select * from table" >> hive-server2.log

3 Comments

HI when I test with echo it is working fine. But while copying the output for next next iterations,it is not working.
ok, but I do not underdstand, it works regardless the number of tests echo is a treatment, it is not related to loops? maybe you could be more clear about: " But while copying the output for next next iterations"
tail -n 0 -f starts reading the file without seeking back. tail -n 1 seeks back and prints the last line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.