skip to Main Content

I have been able to get all login logs in the system for Wednesday. But I am unable to get the first and last login of each day on which it is Wednesday.

Progress so far – `last | grep ‘^[^reboot].*Wed’

Through the above I am achieving this:-

    cent     pts/0        :0               Wed Mar 11 11:57 - 11:41 (19+23:44)
    cent     pts/0        :0               Wed Mar  4 11:10 - 11:57 (7+00:46)
    cent     :0           :0               Wed Mar  4 11:10 - 11:42 (27+00:31)
    cent     pts/0        :0               Wed Jan 22 11:27 - crash (4+10:10)
    cent     :0           :0               Wed Jan 22 11:27 - crash (4+10:10
    cent     pts/0        :0               Wed Jan 22 11:12 - 11:21  (00:09)
    cent     pts/0        :0               Wed Jan  8 11:22 - 11:54 (12+00:32)
    cent     :0           :0               Wed Jan  8 11:21 - down  (14+00:00)

But the expected output should be this:-

    cent     pts/0        :0               Wed Mar 11 11:57 - 11:41 (19+23:44)
    cent     pts/0        :0               Wed Mar  4 11:10 - 11:57 (7+00:46)
    cent     :0           :0               Wed Mar  4 11:10 - 11:42 (27+00:31) 
    cent     pts/0        :0               Wed Jan 22 11:27 - crash (4+10:10)
    //Second entry omitted as we are supposed to only display first and last
    //login each day
    cent     pts/0        :0               Wed Jan 22 11:12 - 11:21  (00:09) 
    cent     pts/0        :0               Wed Jan  8 11:22 - 11:54 (12+00:32)
    cent     :0           :0               Wed Jan  8 11:21 - down  (14+00:00)

2

Answers


  1. You can do it with a simple awk script:

    ##script.awk
    
    # at the end, display the results
    END { for (i in last_login) {
            print i":"
            print "first: " first_full[i] 
            print "last: " last_full[i] 
        }
    }
    
    function add_entry(date, hour, full) {
        # test if last_login login for given date has been set
        if (last_login[date])  {
            # if so, compare with given hour, which is the latest
            if (last_login[date] < hour) {
                #if new hour is the latest, record it and login info
                last_login[date] = hour;
                last_full[date] = full
            } 
        } else {
            # no previous login recorded for this date, record the login
            last_login[date] = hour;
            last_full[date] = full
        }
    
        # same logic in first login
        if (first_login[date])  {
            if (first_login[date] > hour) {
                first_login[date] = hour;
                first_full[date] = full;
            } 
        } else {
            first_login[date] = hour;
            first_full[date] = full;
        }
    }
    
    # if you have `Wed` in line, parse it
    /Wed/ {
        add_entry($5"/"$6, $7, $0)
    }
    

    You can now test it:

    last | awk -f script.awk
    
    Login or Signup to reply.
  2. Try this:

    #! /bin/bash
    
    set -eu
    export LC_ALL=C
    
    # Generate a list of all abbreviations of all months.
    months=($(for d in 1970-{1..12}-1; do date -d $d +%b; done))
    
    # Convert the list of months into a regular expression suitable for sed.
    months_rx=$(tr ' '  '|' <<<"${months[@]}" | sed 's/|/\|/g')
    
    # Read `last`s output into a variable, because we need it more than once.
    last="$(last -F)"
    
    # Build a list of date patterns for all Wednesdays, when a login happened.
    dates=$(sed -n 's/.*Wed ('"$months_rx"') (..) ..:..:.. (....) - .*/1 2 ..:..:.. 3/p' <<<"$last" | uniq)
    
    # Filter `last`s output for each date pattern and print the first and last line.
    while read d; do
      sed -n "/$d - /p" <<<"$last" | sed -n '1p;$p'
    done <<<"$dates"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search