web-dev-qa-db-ja.com

awkを使用して当月の毎日のログイン数を取得するにはどうすればよいですか?

今月、サーバーに毎日ログインしているユーザーの数を調べたい。月の最初の日から開始します。これを行うためにawkを使用したいと思います。
出力は次のようになります。

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

あなたは以下のようにそれを使うことができます:

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

OR

ユーザーごとのリスト:

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

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を使用していない場合は同等)に追加することで、シェル関数にすることができます。

_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を実行して、目的の出力を取得できます。

または、rebootwtmpをフィルターで除外する代わりに、既存のユーザー名のみをフィルターに掛けることもできます(シェルが<()構成をサポートしていると仮定)。

_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
}
_
2
terdon

スターリン・ヴィニェシュ・クマールの回答に感謝します。このコードは、システムの月(date +%b)によって決定される現在の月のみを表示し、再起動ユーザーを除外します。これは、lastコマンドの出力に常にシステムが起動し、allユーザーのログインを表示します。適切な変数の出力に先行ゼロを追加する方法がわかれば、答えを更新します。

#!/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
0
Deputy Cartman