1

I was wondering how I would go around to do this.

This is an example of my output

Sun Aug 21 2016 03:00:00, BLAH
Mon Aug 22 2016 03:54:00, BLAH
Tue Aug 23 2016 04:22:11, BLAH
Thu Aug 25 2016 05:00:00, BLAH

Now what I would like to do is only count consecutive days so in the example above it should say BLAH appeared 3 times as they are after each other.

I have bash, awk, and sed available.

  • 1
    what about days that wrap to a new month? year? leap days? – Jeff Schaller Aug 25 '16 at 19:46
  • here's a hint: with GNU date, you can do date -d "Sun Aug 21 2016 03:00:00 1 day ago" "+%b %e" to get Aug 20 – glenn jackman Aug 25 '16 at 20:04
1

In AWK:

{
    sub(",", "", $0);  # kill first comma, thanks Thomas
    cmd="date -d \""$1" "$2" "$3" "$4" "$5" 1 day ago\" \"+%b %e\"";
    cmd|getline dt;
    close(cmd);
    if (dt==prev && blah==substr($0, index($0, $6))) { times = times + 1 }
    else { print times" "line; times = 1 };
    prev=$2" "$3;
    blah=substr($0, index($0,$6));
    line=$0;
}
END { print times" "line }

Assuming we have this input inside a file called blah.log:

Sun Aug 21 2016 03:00:00, BLAH
Mon Aug 22 2016 03:54:00, BLAH
Tue Aug 23 2016 04:22:11, BLAH
Thu Aug 25 2016 05:00:00, BLAH

And the awk script in consecutive.awk, we can do:

$ awk -f consecutive.awk blah.log

3 Tue Aug 23 2016 04:22:11 BLAH
1 Thu Aug 25 2016 05:00:00 BLAH

Which gives the number of consecutive days as an extra column and prints the last date. To get rid of the date in the output you can simply change print times" "line to print times" "blah (in the two places that is appears).

How does it work:

  • Executes the date command to get Yesterday of the current line, thanks glenn jackman
  • Compares against saved date from the previous line
  • Increments a counter or prints
  • Saves data from current line for next run

Notes:

  • It is ugly (all AWK code is, get over it)
  • Works well across any gaps (up to an entire year) because it uses date, but disregards timezones
  • It considers that BLAH may be different on different lines and only matches BLAH occurrences against other BLAH occurrences. If the file is not well ordered you may need to perform a sort -t , -k 2.
  • If you need to consider for different values of BLAH you need GNU awk (thanks to the substr call). Otherwise you can kill the substr call and the script will run on any posix awk.
  • It appears that you could dispense with tr by copying $0 to a variable and chopping it up a little. OP did not mention tr in the set of tools available. – Thomas Dickey Aug 26 '16 at 0:30
  • @ThomasDickey - good point, I was stupid to worry about that subst in non-posix, but there is also plain sub, thanks – grochmal Aug 26 '16 at 0:52
0

This took more than I thought it would but the script below will do the job.

#!/bin/bash
str=" Sun Aug 21 2016 03:00:00, BLAH Mon Aug 22 2016 03:54:00, BLAH"
str+=" Tue Aug 23 2016 04:22:11, BLAH Thu Aug 25 2016 05:00:00, BLAH"
IFS='H' read -r -a inputArray <<< "$str"
days=(SunMon MonTue TueWed WedThu ThuFri FriSat SatSun)
count=1
found=0
lastOne=""
finalCount=0
for entry in "${inputArray[@]}"; do
   thisOne="${entry:1:3}"
   test="$lastOne$thisOne"
   for pair in "${days[@]}"; do
      if [ "$test" == "$pair" ]; then
         ((++count, ++found))
      fi
   done
   if [ ! $found ]; then count=1; else found=0; fi
   if [ $count -gt $finalCount ]; then
      finalCount=$count
   fi
   lastOne=$thisOne
done
echo "There were $finalCount BLAHs in a row."
  • That relies on having no gaps of a week or more. – Thomas Dickey Aug 25 '16 at 23:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.