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