0

I am just trying to check the alert.log file, if it is having the word (line? ed.) count greater than 4 and the word Time is there in it, then I will grep only for Time and it will print the latest timestamp. But if Time is not there, it should print the current date.

I wanted to check the word count and grep criteria in one condition.

if [[ -s "${SCRIPT_PATH}/alert.log" ]]; then
    if test `cat alert.log | wc -l` -gt 4 ;    
    then
        if test -s `cat alert.log | grep -i Time`;            
        then
            cat alert.log | tail -r | grep -i Time > latest_time.out
            CURRENT_TIMESTAMP=`cat latest_time.out | head -1 | grep "Time:*" | cut -f2 -d":"`
            echo $CURRENT_TIMESTAMP
            rm alert.log
        fi         
    fi
else
    CURRENT_TIMESTAMP=$( date +%Y-%m-%d )
    echo $CURRENT_TIMESTAMP
fi

If I execute this script and if alert.log does not contain the word time, it should print the current timestamp, but it's not working. And when I checked separately, I found that `cat alert.log | wc -l` -gt 4, this part is not working. What's wrong?

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • That's an awful amount of pretzel logic and [useless use of `cat`](http://www.iki.fi/era/unix/award.html). Can you summarize what your script should do, and perhaps post a `bash -x` trace from the specific command you are having trouble with? – tripleee Aug 27 '15 at 07:19
  • Replacing everything in the first branch with a simple Awk script would be a lot more succinct, readable, understandable, and efficient. Make it `exit 1` if any of the conditions fail, so you can use it *instead of* `test` and `[[`. – tripleee Aug 27 '15 at 07:23
  • The first condition looks for `$SCRIPT_PATH/alert.log` while subsequent conditions lack the path. Unless you are running in that directory, they will refer to different files; and most places, the file will be nonexistent. – tripleee Aug 27 '15 at 07:26
  • The script will be running from the same path where the logs will be there – Kalpna Kashyap Aug 27 '15 at 08:43

1 Answers1

1

Without the output from bash -x it is hard to say exactly what is going wrong; but the following code should perform the logic more efficiently as well as more idiomatically.

if CURRENT_TIMESTAMP=$(awk 'tolower($1) == "time:" { t=$2 }
      END { if (NR>4 && t) { print t } else { exit 1 } }' alert.log); then
    rm alert.log
else
    CURRENT_TIMESTAMP=$(date +%Y-%m-%d)
fi
# repeated echo refactored to be performed only once, after condition
echo "$CURRENT_TIMESTAMP"

The Awk script contains a couple of additional assumptions -- specifically, that the Time: marker will always be the first token on the line, and that the datestamp will be the second token on that line. If the input file doesn't exist, Awk will fail; if it contains four lines or fewer, or doesn't contain any match, the END clause will exit 1 which also signals a failure to if. (There will be an error message from Awk if the input file does not exist, but I would normally regard that as a feature. Add a redirection of standard error if you want Awk to run quietly. awk '... stuff ...' alert.log 2>/dev/null)

Because Awk runs through the file just once, the logic is more efficient than your repeated cat and grep and head and tail logic. The value of the Awk script's variable t will be overwritten on each new match, so the printed value will be from the last match in the file.

tripleee
  • 175,061
  • 34
  • 275
  • 318