Home > Net >  Get the longest logon time of a given user using awk
Get the longest logon time of a given user using awk

Time:04-23

My task is to write a bash script, using awk, to find the longest logon of a given user ("still logged in" does not count), and print the month day IP logon time in minutes.

Sample input:./scriptname.sh username1

The content of last username1:

username1       pts/        IP      Apr     2       ..      ..      ..      ..      (00.03)

username1       pts/        IP      Apr     3       ..      ..      ..      ..      (00.13)

username1       pts/        IP      Apr     5       ..      ..      ..      ..      (12.00)

username1       pts/        IP      Apr     9       ..      ..      ..      ..      (12.11)

Sample output:

Apr 9 IP 731 (expl: 12 hours and 11 minutes is in total 731 minutes)

I have written this script, but a bunch of errors pop up, and I am really confused:

#!/bin/bash

usr=$1

last $usr | grep -v "still logged in" | awk 'BEGIN {max=-1;}
                                                {
                                                h=substr($10,2,2);
                                                min=substr($10,5,2)   h/60;
                                                }
                                                (max < min){
                                                max = min;
                                                }
                                                END{
                                                maxh=max/60;
                                                maxmin=max-maxh;
                                                ($maxh == 0 && $maxmin >=10){
                                                        last $usr | grep "00:$maxmin" | awk '{print $5," ",$6," ", $3," ",$maxmin}'
                                                        exit 1
                                                }
                                                ($maxh == 0 $$ $maxmin < 10){
                                                        last $usr | grep "00:0$maxmin" | awk '{print $5," ",$6," ",$3," ",$maxmin}'
                                                        exit 1
                                                }
                                                ($maxh < 10 && $maxmin == 0){
                                                        last $usr | grep "0$maxh:00" | awk '{print $5," ",$6," ",$3," ",$maxmin}'
                                                        exit 1
                                                }
                                                ($maxh < 10 && $maxmin < 10){
                                                        last $usr | grep "0$maxh:0$maxmin" | awk '{print $5," ",$6," ",$3," ",$maxmin}'
                                                        exit 1
                                                }
                                                ($maxh >= 10 && $maxmin < 10){
                                                        last $usr | grep "$maxh:0$maxmin" | awk '{print $5," ",$6," ",$3," ",$maxmin}'
                                                        exit 1
                                                }
                                                ($maxh >=10 && $maxmin >= 10){
                                                        last $usr | grep "$maxh:$maxmin" | awk '{print $5," ",$6," ",$3," ",$maxmin}'
                                                        exit 1
                                                }
                                                }'

So a bit of explaining of how I imagined this would work:

After the initialization, I want to find the (hh:mm) column of the last $usr command, save the h and min of every line, find the biggest number (in minutes, meaning it is the longest logon time).

After I found the longest logon time (in minutes, stored in the variable max), I then have to reformat the only minutes format to hh:mm to be able to use a grep, use the last command again, but now only searching for the line(s) that contain the max logon time, and print all of the needed information in the month day IP logon time in minutes format, using another awk.

Errors I get when running this code: A bunch of syntax errors when I try using grep and awk inside the original awk.

CodePudding user response:

For the content of last username1 you might keep track of the line with the highest number, and in the END block print the format that you want.

If in this example, file contains the example content, and the last column contains the logon:

awk '
$(NF) ~ /\([0-9][0-9].[0-9][0-9]\)/ {      # if the last field matches the pattern
  tmp = $(NF)                              # value of the last field
  gsub(/[().]/, "", tmp)                   # remove ( ) .
  if(tmp > max) max = tmp; line = $0       # keep track of the highest value
}
END{                      
  n = split(line,a,/[[:space:]] /)         # split the line variable on 1  spaces
  hours = substr(a[n],2,2) * 60            # get the hours part, where a[n] is the last element of array a
  minutes = substr(a[n], 5, 2)             # the minutes part
  print a[3], a[4], a[5], hours   minutes  # print the custom output
}
' file

Output

IP Apr 9 731

CodePudding user response:

Using any awk in any shell on every Unix box and assuming if multiple rows have the max time you'd want all of them printed (easy tweak if not, just tell us your requirements for that case and include it in the example in your question):

last username1 |
awk '
    /still logged in/ {
        next
    }
    {
        split($NF,t,/[().]/)
        cur = (t[2] * 60)   t[3]
    }
    cur >= max {
        out = ( cur > max ? "" : out ORS ) $4 OFS $5 OFS $3 OFS cur
        max = cur
    }
    END {
        print (out ? out : "No matching records")
    }
'
Apr 9 IP 731
  • Related