다음 항목이 포함된 거대한 로그 파일 access.log가 있습니다.
192.11.111.111 - - [05/Mar/2021:00:00:02 +0100] "GET ..."
192.250.14.80 - - [05/Mar/2021:00:00:09 +0100] "GET ..."
12.249.66.42 - - [05/Mar/2021:00:00:13 +0100] "GET ..."
지난 시간의 항목만 가져오거나 필터링하는 방법은 무엇입니까?
답변1
#!/bin/bash
age() { python -c '
import sys
from datetime import datetime
print(int((datetime.now() - datetime.strptime(sys.argv[1], sys.argv[2])).seconds))
' "$@"
}
tac access.log | while IFS= read line; do
date=$(cut -d' ' -f4 <<< "$line")
age=$(age "$date" "[%d/%b/%Y:%H:%M:%S")
[ $age -gt 3600 ] && break
printf '%s\n' "$line"
done
설명하다:
- 날짜 문자열의 나이를 가져오는 함수를 만들기 위해
python
datetime
모듈을 사용하고 있습니다. - 그런 다음 파일의 행을 역방향으로 반복하십시오.
tac log | while ...
- 날짜 문자열을 가져오는 데 사용합니다
cut
.-d' '
구분 기호가 공백이 아닌 탭인 경우 제거해야 합니다.- 또는
awk '{print $4}' <<< "$line"
대신 사용 - 또는
read ip some thing date tz else <<< "$line"
)을 사용하세요.
- 첫 번째 단계에서 정의한 함수를 사용하여 나이를 가져옵니다.
- 초 > 3600(=1시간)이면 루프를 중지합니다(
break
). - 그렇지 않으면 해당 줄을 인쇄하십시오(또는 무엇이든 수행하십시오).
몇 가지 추가 참고 사항:
시간대(+0100)를 무시하고 있으므로 여기서는 로그 파일과 동일한 시간대에 있다고 가정합니다. 다른 시간대에 로그 파일이 있는 경우 이 기능을 개선할 수 있습니다
age
.이봐날짜를 로 읽습니다cut -d' ' -f4,5
.분명히 를 사용하여 전체 작업을 수행할 수 있지만
python
전체 파일을 읽을 필요 없이 파일을 역순으로 읽을 수 있습니다.그리 쉽지는 않은 것 같다나 이거 굉장히 좋아tac
.date
나이를 계산하려면 및bc
등을 사용할 수 있습니다 (여기서 했던 것처럼), 그러나 날짜 형식은 기본적으로 지원되지 않으므로 이는 고통스러울 것입니다. 아이고,datetime.strptime
딱 맞아요.이 기능의 장점은
age
모든 종류의 작업에 재사용이 가능하다는 것입니다. 그냥 똑같이 부르면strptime
읽을 수 있습니다.여기에 녹음하세요.age "date_string" "format"