Reputation: 665
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.
Upvotes: 0
Views: 114
Reputation: 583
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
tail -n 0 -f
starts reading the file without seeking backtail -n 1 -f
seeks back and prints the last lineecho "select * from table" >> hive-server2.log
Upvotes: 0
Reputation: 189387
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
.
Upvotes: 1