我的任務是使用 awk 撰寫一個 bash 腳本來查找給定用戶的最長登錄時間(“仍然登錄”不計算在內),并列印month day IP logon time in minutes.
樣本輸入:./scriptname.sh username1
的內容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)
樣本輸出:
Apr 9 IP 731
(解釋:12小時11分鐘總共731分鐘)
我寫了這個腳本,但是彈出一堆錯誤,我真的很困惑:
#!/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
}
}'
所以有點解釋我想象這會如何作業:
初始化后,我想找到命令的(hh:mm)列last $usr,保存每一行的h和min,找到最大的數字(以分鐘為單位,表示最長的登錄時間)。
在我找到最長的登錄時間(以分鐘為單位,存盤在變數中max)之后,我必須重新格式化唯一的分鐘格式才能hh:mm使用 grep,再次使用最后一個命令,但現在只搜索該行(s ) 包含max登錄時間,并month day IP logon time in minutes使用另一個awk.
運行此代碼時遇到的錯誤:當我嘗試在原始代碼中使用grep時出現一堆語法錯誤。awkawk
uj5u.com熱心網友回復:
awk 不是外殼。您不能直接呼叫 , 之類的工具last,grep也不能直接awk從程式awk呼叫它們C。
在每個 Unix 機器上的任何 shell 中使用任何 awk 并假設如果多行具有您希望全部列印的最大時間,并且如果沒有找到帶時間戳的行,您想要No matching records列印類似的內容(如果沒有,請輕松調整,只需告訴我們您的這些情況的要求并將它們包含在您問題的示例中):
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
uj5u.com熱心網友回復:
如果gnu-awk可用,您可以對最后一個欄位中的數字使用具有 2 個捕獲組的模式。在 END 塊中列印您想要的格式。
如果在此示例中,file包含示例內容,并且最后一列包含登錄:
awk '
match ($(NF), /\(([0-9] )\.([0-9] )\)/, a) {
hm = (a[1] * 60) a[2]
if(hm > max) {max = hm; line = $0;}
}
END {
n = split(line,a,/[[:space:]] /)
print a[3], a[4], a[5], max
}
' file
輸出
IP Apr 9 731
uj5u.com熱心網友回復:
在我的機器上測驗last命令:
使用 Red Hat Linux 7.8 得到以下輸出:
user0022 pts/1 10.164.240.158 Sat Apr 25 19:32 - 19:47 (00:14)
user0022 pts/1 10.164.243.80 Sat Apr 18 22:31 - 23:31 (1 01:00)
user0022 pts/1 10.164.243.164 Sat Apr 18 19:21 - 22:05 (02:43)
user0011 pts/0 10.70.187.1 Thu Nov 21 15:26 - 18:37 (03:10)
user0011 pts/0 10.70.187.1 Thu Nov 7 16:21 - 16:59 (00:38)
astukals pts/0 10.70.187.1 Mon Oct 7 19:10 - 19:13 (00:03)
reboot system boot 3.10.0-957.10.1. Mon Oct 7 22:09 - 14:30 (156 17:21)
astukals pts/0 10.70.187.1 Mon Oct 7 18:56 - 19:08 (00:12)
reboot system boot 3.10.0-957.10.1. Mon Oct 7 21:53 - 19:08 (-2:-44)
IT pts/0 10.70.187.1 Mon Oct 7 18:50 - 18:53 (00:03)
IT tty1 Mon Oct 7 18:48 - 18:49 (00:00)
user0022 pts/1 30.30.30.168 Thu Apr 16 09:43 - 14:54 (05:11)
user0022 pts/1 30.30.30.59 Wed Apr 15 11:48 - 04:59 (17:11)
user0022 pts/1 30.30.30.44 Tue Apr 14 19:03 - 04:14 (09:11)
發現時間格式DD HH:MM僅在DD不為零時出現。
發現還有額外的技術用戶:IT, system,reboot需要過濾。
建議解決方案:
last | awk 'BEGIN {FS="[ () :]*"}
/reboot|system|still/{next}
{ print $5 OFS $6 OFS $3 OFS $(NF-1) ($(NF-2) * 60) ($(NF-3) * 60 * 24)}
' |sort -nk 4| head -1
結果:
Apr 15 30.30.30.59 85991
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/463876.html
