awkを使用して毎月毎日ログイン数を取得するには?

awkを使用して毎月毎日ログイン数を取得するには?

毎月私のサーバーに毎日ログインしているユーザーの数を知りたいです。毎月1日から始まります。これを行うには、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を使用しない場合はそれに対応する)エントリに追加してそれをシェル関数に置き換えることができます。

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して目的の出力を得ることができます。

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

回答をいただいたStalin Vignesh Kumarに感謝します。このコードはシステムウォール(日付+%b)、再起動ユーザーをフィルタリングして次に表示します。最後システムが起動して表示されるたびにコマンドの出力みんなユーザーのログイン。適切な変数の出力に先行ゼロを追加する方法がわかったら、答えを更新します。

#!/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

関連情報