如何使用 awk 获取当月每天的登录次数?

如何使用 awk 获取当月每天的登录次数?

我想了解当月每天有多少用户登录我的服务器。从每个月的第一天开始。我最好使用 awk 来做到这一点。
我的输出应该是这样的:

Apr 1: numOfLogins
Apr 2: numOfLogins
...
current day: numOfLogins

答案1

您可以像下面这样使用它:

last <user>  | awk -v dt="$(date +%b)" '$5==dt{ k[$5$6]+=1; a[$5$6]=$5"-"$6"-"$7  } END { for ( i in k ) { split(a[i],s,"-");print s[1]" "s[2]": "k[i]" No of Logins"  } }' | sort -n -k2

对于非特定用户:

last | grep -ve reboot -ve wtmp | awk -v dt="$(date +%b)" '$5==dt{ k[$5$6]+=1; a[$5$6]=$5"-"$6"-"$7  } END { for ( i in k ) { split(a[i],s,"-");print s[1]" "s[2]": "k[i]" No of Logins"  } }' | sort -n -k2

或者

按用户列出:

last | grep -ve reboot -ve wtmp | awk -v dt="$(date +%b)" '$5==dt{ k[$1$5$6]+=1; a[$1$5$6]=$1"-"$5"-"$6"-"$7  } END { for ( i in k ) { split(a[i],s,"-");print s[1]" "s[2]" "s[3]": "k[i]" No of Logins"  } }' | sort -n -k3

答案2

如果您last支持该--since选项,您可以通过以下方式限制为当前月份:

last --since "$(date +'%Y-%m-01')"

该命令date +'%Y-%m-01'打印本月第一天的日期。例如,如果我今天(2020 年 4 月 26 日)运行它,我会得到:

$ date +'%Y-%m-01'
2020-04-01

所以last命令变成了last --since 2020-04-01

这意味着我们在 awk 中需要做的就是排除以 开头的行reboot、以 开头的行wmtp以及任何空行,然后进行计数:

last --since "$(date +'%Y-%m-01')" | awk '!/^reboot/&&!/^wtmp /&&/./{date=$5" "$6; a[date]++}END{for(date in a){printf "%s: %d\n",date,a[date]}}' | sort -nk2

或者,更容易阅读:

last --since "$(date +'%Y-%m-01')" | 
    awk '!/^reboot/ && !/^wtmp / && /./{
        date=$5" "$6; 
        a[date]++
       }
       END{
        for(date in a){
            printf "%s: %d\n",date,a[date]
        }
       }' | sort -nk2

在我的笔记本电脑上,返回:

$ last --since "$(date +'%Y-%m-01')" | awk '!/^reboot/&&!/^wtmp / && /./{date=$5" "$6; a[date]++}END{for(date in a){printf "%s: %d\n",date,a[date]}}' | sort -nk2
Apr 3: 1
Apr 5: 1
Apr 20: 1

~/.bashrc如果这是您经常使用的东西,您可以通过将这些行添加到您的(或等效的,如果您不使用 bash)中,将其变成 shell 函数:

monthLogins(){
    last --since "$(date +'%Y-%m-01')" | 
        awk '!/^reboot/ && !/^wtmp / && /./{
            date=$5" "$6; 
            a[date]++
           }
           END{
            for(date in a){
                printf "%s: %d\n",date,a[date]
            }
           }' | sort -nk2
}

然后您可以运行monthLogins并获得所需的输出。

或者,您可以使用以下命令仅过滤现有用户名(假设您的 shell 支持该构造),而不是过滤掉reboot和:wtmp<()

monthLogins(){
    last --since "$(date +'%Y-%m-01')" | 
     grep -f <(cut -d: -f1 /etc/passwd)
        awk '/./{
            date=$5" "$6; 
            a[date]++
           }
           END{
            for(date in a){
                printf "%s: %d\n",date,a[date]
            }
           }' | sort -nk2
}

答案3

非常感谢斯大林·维涅什·库马尔的回答。此代码将仅显示由系统月份确定的当前月份(日期+%b),过滤掉reboot用户,显示在最后的每当系统启动时命令的输出,并显示全部用户的登录。如果我能弄清楚如何在适当变量的输出中添加前导零,我将更新我的答案:

#!/bin/bash
last | grep `date +%b` | grep -v -e "reboot" | awk ' { k[$5$6]+=1; a[$5$6]=$5"-"$6"-"$7  } END { for ( i in k ) { split(a[i]"\n",s,"-");print s[1]" "s[2]": "k[i]" logins"  } }' | sort -n -k2

相关内容