이 커뮤니티에 처음 들어왔습니다. 나는 bash 스크립트에서 이 작업을 수행합니다. 내 질문은 내가 찾고 있는 것을 거의 요약하고 있습니다. 여러 개의 IP 주소와 기타 데이터가 포함된 로그 파일이 있습니다. 각 특정 날짜의 고유 IP 주소 수를 계산하여 변수에 저장하고 싶습니다. grep과 awk를 사용하여 이를 수행하는 방법에 대한 아이디어가 있습니까?
날짜 형식은 2020년 2월 11일입니다(예시임).
로그 파일의 예제 텍스트:
57.34.156.99 - - [11/Feb/2020:04:32:18 +0330]
43.21.223.33 - - [11/Feb/2020:09:13:05 +0330]
87.44.212.82 - - [14/Mar/2020:06:22:01 +0330]
43.21.223.33 - - [11/Feb/2020:11:05:32 +0330]
위의 출력은 다음과 같습니다.
11/Feb/2020:2
14/Mar/2020:1
보시다시피 중복된 IP 주소는 한 번만 계산하고 싶습니다.
도움을 주시면 감사하겠습니다. 더 많은 정보를 제공해야 한다면 알려주시기 바랍니다.
답변1
이는 질문의 예제 형식에 대한 답변이지만 일반적으로 프로세스는 다른 로그 형식과 유사합니다(일반적으로 날짜는 ISO 형식이고 첫 번째 필드에 있습니다). 작업과 형식을 분리하려면 먼저 IP와 날짜만 살펴보세요.
> awk '{print substr($4,2,10), $1}' file
11/Feb/202 57.34.156.99
11/Feb/202 43.21.223.33
14/Mar/202 87.44.212.82
11/Feb/202 43.21.223.33
해시가 날짜와 IP이고 "date-ip"로 증가되는 연관 배열을 사용할 수 있습니다. 실제 결과를 계산하는 데 또 다른 배열이 사용되며, 여기서 해시는 날짜일 뿐입니다.
awk '{d = substr($4,2,10)} !seen[d FS $1]++ {cnt[d]++}
END {for (x in cnt) print x ":" cnt[x]}
' file | sort -t ":" -rnk2
산출:
11/Feb/202:2
14/Mar/202:1
cnt
배열의 순서는 정의되지 않았으므로 ip count 를 통해END
날짜를 파이프하는 것이 유용합니다 .sort
아니면 당신은 사용할 수 있습니다GNU awk 배열 정렬 기능.의 변수는 암시적으로 정의되지 않으며 처음에는 0이거나 빈 문자열이므로
awk
새로운 "date-ip" 집합에 대해!seen[date-ip]++
true가 되며 그 이후에는 변수가 증가합니다. 따라서 다음에 이 "date-ip"를 만나면 이는 false가 되며 이를 증가시키지 않습니다cnt[date]
.
각 줄에서 "date-ip"만 추출한 후 sort
동일한 작업을 수행합니다 .uniq
> awk '{print substr($4,2,10), $1}' file | sort -u | awk '{print $1}' | uniq -c
2 11/Feb/202
1 14/Mar/202
여기서는 정렬하는 동안 중복 항목을 제거하고 sort -u
( uniq
입력은 나중에 정렬해야 하기 때문에) 첫 번째 필드(날짜)만 유지하고 마지막으로 uniq -c
각 고유 날짜의 개수를 인쇄합니다. 이 내용은 익숙하지 않은 사람들이 더 쉽게 읽을 수 있습니다 awk
. 프로세스를 시연하기 위해 명령의 각 단계를 인쇄하여 진행 상황을 확인할 수 있습니다.