Hi. I need to count multiple occurrences of X Y Z in a file in 1 go. At the moment I have the following scripts:
ssh readonly@$ServerIP 'YEAR=xx;DAY=xx;MONTH=xx;LMONTH=xx;for i in 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \
16 17 18 19 20 21 22 23; do cat /var/SP/log/cre/access.log_$YEAR$MONTH$DAY*_$i | grep -c "HTTP/1.1\" \"503";done'>>$sshEF
this goes for HTTP1.1 503... then there is 500, 400, 403 and 404 which runs the same thing..
Now I have to look for HTTP response codes in the hourly log files on an apache web server.. and count them.
At the moment my grep command runs through the log files once for each response type.
I have also tried
var_500=0;var_503=0;var_400=0;var_403=0;var_404=0
for i in 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23;
do cat /var/SP/log/cre/access.log_$YEAR$MONTH$DAY*$i | while read line
do
variable=`echo $line | awk '{print$7}'` #print response code with awk
case $variable in #ERRORS 1
500 ) var_500=`expr $var_500 + 1`;;
503 ) var_503=`expr $var_503 + 1`;;
400 ) var_400=`expr $var_400 + 1`;;
403 ) var_403=`expr $var_403 + 1`;;
404 ) var_404=`expr $var_404 + 1`;;
* ) hello=hello
esac
datetime=$i
Server=`hostname`
date="$YEAR/$MONTH/$DAY"
for p in 500 503 400 403 404;
do
err_desc="HTTP/1.1 $p"
Value=`echo $(var$p)`
echo "vl$Servername,$date,$err_desc,$Value"
done
done
But the CPU utilization and time is too long to be a viable solution. ( 4min CPU time at over 3% utilization, whereas the grep -c is 10 seconds @ 0.1%)
Is there an easy way to count multiple things in a file in one go? Or should I just stick with grep -c?
Sure you can. Either by variable substitution inside awk code or by assigning the sell variable to a awk variable with the -v switch. The GNU Awk User's Guide
Instead of looping through your log files and executing the awk code block on every loop, why don't you input all these files into awk like:
awk 'awk code block' file1 file2 file3
This would enable you to use the awk FILENAME variable to print the file name in front of the results.
awk '{total[FILENAME" "$10] += 1} END{for (i in total) print "HTTP/1.1 "i, total}' file1 file2 file3