今月、サーバーに毎日ログインしているユーザーの数を調べたい。月の最初の日から開始します。これを行うためにawkを使用したいと思います。
出力は次のようになります。
Apr 1: numOfLogins
Apr 2: numOfLogins
...
current day: numOfLogins
あなたは以下のようにそれを使うことができます:
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
を実行して、目的の出力を取得できます。
または、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
}
_
スターリン・ヴィニェシュ・クマールの回答に感謝します。このコードは、システムの月(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