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), 재부팅 사용자를 필터링하고 다음에 표시합니다.마지막시스템이 시작되고 표시될 때마다 명령의 출력모두사용자의 로그인. 적절한 변수의 출력에 선행 0을 추가하는 방법을 알아낼 수 있으면 답변을 업데이트하겠습니다.

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

관련 정보