Code:
$ cat batmon.sh
#!/bin/bash
# Loop over all commandline parameters 2011-*
while [ "$#" -gt 0 ]
do
BASE=$(basename "$1")
# The datafiles contain \r, which must be stripped somehow
while IFS=$'\r\n' read LINE
do
# Convert HH:MM:SS into HH,MM,SS to make awk easier
TIME="${LINE:4:8}" ; TIME="${TIME//:/,}"
# We also convert YYYY-MM-DD into YYYY,MM,DD
echo "${BASE//-/,},${LINE:0:2},${TIME},${LINE:13}"
done < "$1/LogFile.txt"
shift
done | tee output.txt | awk -F "," '
BEGIN { OT=0 # Time of previous measurement
MAX=0 # Max num of seconds between valid events
DAY=""; # Current day
CA=0 ; CB=0
# Running total of bats leaving and entering
TOTALBATS=0;
# The highest TOTALBATS has ever been
MAXBATS=0;
# Length of the patterns
L=4
# Patterns to check against
# Block 1 Block 0 Unblock 1 Unblock 0
A[0]="1,1"; A[1]="0,1"; A[2]="1,0"; A[3]="0,0";
# Block 0 Block 1 Unblock 0 Unblock 1
B[0]="0,1"; B[1]="1,1"; B[2]="0,0"; B[3]="1,0";
# A[0]="0,0"; A[1]="0,1"; A[2]="1,1"
# B[0]="0,0"; B[1]="1,0"; B[2]="1,1"
}
{
if((DAY != $1 $2 $3) && (DAY != ""))
{
I=TOTALBATS; if(I<0) I=-I;
STR=sprintf("COUNT@%s COUNT %+d RET %d LEFT %d GUESS %d", DAY,
TOTALBATS, MAXBATS, -MINBATS, I);
print STR >"/dev/stderr"
TOTALBATS=0;
MAXBATS=0;
MINBATS=0;
}
DAY=$1 $2 $3;
if($8 == "pv")
{ # Calculate number of seconds from date
# Needs GAWK.
T=mktime($1 " " $2 " " $3 " " $5 " " $6 " " $7);
# If too much time has passed since the last event, start over.
if((T-OT) > MAX) # Blank the array
for(N=0; N<(L-1); N++) C[N]="";
else # Shift elements toward the front
for(N=0; N<(L-1); N++) C[N]=C[N+1];
OT=T # Set prev time to this one.
C[L-1]=$9 "," $10; # Set the latest event in the array
FOUNDA=1; FOUNDB=1;
for(N=0; N<L; N++)
{
if(A[N] != C[N]) FOUNDA=0;
if(B[N] != C[N]) FOUNDB=0;
}
# DAY=$1 $2 $3;
# Count the events and mark the hour they occurred in
if(FOUNDA)
{
printf("A@%s-%s-%s %s:%s:%s\n",$1,$2,$3,$5,$6,$7);
CA++; AH[$5]++;
TOTALBATS++;
}
if(FOUNDB)
{
printf("B@%s-%s-%s %s:%s:%s\n",$1,$2,$3,$5,$6,$7);
CB++; BH[$5]++;
TOTALBATS--;
}
if(MAXBATS < TOTALBATS) MAXBATS=TOTALBATS;
if(MINBATS > TOTALBATS) MINBATS=TOTALBATS;
}
}
END { # The final statistics will be printed to stderr, to easily
# seperate them from the event times printed to stdout.
# The last daily count
I=TOTALBATS; if(I<0) I=-I;
STR=sprintf("COUNT@%s COUNT %+d RET %d LEFT %d GUESS %d", DAY,
TOTALBATS, MAXBATS, -MINBATS, I);
print STR >"/dev/stderr"
# Print the event counts
printf("A %2d\nB %2d\nT %2d\nM %2d\n", CA, CB, CA+CB, MAXBATS) > "/dev/stderr";
# Print a list of hours from 1-23
STR="H";
for(N=1; N<=23; N++) STR=STR sprintf(" %2d", N);;
print STR > "/dev/stderr";
# Print hourly counts for event A
STR="A";
for(N=1; N<=23; N++)
STR=STR sprintf(" %2d", AH[sprintf("%02d", N)]);
print STR > "/dev/stderr";
# Hourly counts for event B
STR="B";
for(N=1; N<=23; N++)
STR=STR sprintf(" %2d", BH[sprintf("%02d",N)]);
print STR > "/dev/stderr";
}'
$ ./batmon.sh 2011* > /dev/null
COUNT@20110123 COUNT -2 RET 0 LEFT 4 GUESS 2
COUNT@20110124 COUNT +3 RET 3 LEFT 2 GUESS 3
COUNT@20110125 COUNT +2 RET 2 LEFT 1 GUESS 2
COUNT@20110126 COUNT +0 RET 0 LEFT 0 GUESS 0
COUNT@20110127 COUNT +0 RET 0 LEFT 0 GUESS 0
COUNT@20110128 COUNT +3 RET 3 LEFT 2 GUESS 3
COUNT@20110129 COUNT -1 RET 0 LEFT 3 GUESS 1
COUNT@20110130 COUNT -6 RET 0 LEFT 8 GUESS 6
COUNT@20110131 COUNT -8 RET 2 LEFT 10 GUESS 8
COUNT@20110201 COUNT +0 RET 0 LEFT 0 GUESS 0
COUNT@20110202 COUNT +0 RET 0 LEFT 0 GUESS 0
A 65
B 74
T 139
M 0
H 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
A 2 4 0 0 1 1 1 0 4 10 4 9 6 2 4 2 5 3 3 3 1 0 0
B 3 2 0 1 0 0 0 4 12 8 12 9 4 2 2 0 5 1 7 2 0 0 0
$