액세스 로그는 대략 시간별로 정렬되지만 uniq -c
연결을 시간( )별로 집계하려면 더 많이 정렬해야 합니다. 대규모 액세스 로그의 경우 정렬은 인쇄하기 전에 전체 파일을 버퍼링하고 정렬하기 때문에 매우 비효율적입니다.
한 번에 주어진 수의 행만 정렬하여 블록을 인쇄하는 정렬 옵션이나 정렬 버전을 알고 계십니까?
"스트림 정렬", "블록 정렬", "근사 정렬"이라는 키워드를 검색했습니다. 설명서 전체를 읽었는데 쓸모가 없습니다. 버퍼 크기(-S) 설정은 이에 영향을 미치지 않습니다.
답변1
tail -f access_log | awk -v 'cmd=sort --OPTION-IN-QUESTION | uniq -c' '
{print $4, $1 | cmd}
NR % 1000 == 0 {close(cmd)}'
답변2
노력하다 split --filter
:
split --lines 1000 --filter 'sort ... | sed ... | uniq -c' access.log
이는 1000개 행의 청크로 분할되고 access.log
지정된 필터를 통해 각 청크를 파이프합니다.
각 블록의 결과를 별도로 저장하려면 $FILE
필터 명령에서 접두사(기본값)를 사용하고 지정할 수 있습니다 x
.
split --lines 1000 --filter '... | uniq -c >$FILE' access.log myanalysis-
myanalysis-aa
그러면 첫 번째 청크, 두 번째 청크 등을 처리 한 결과가 포함된 파일이 생성됩니다 .myanalysis-ab
이 --filter
옵션은 split
GNU coreutils 8.13(2011년 9월 출시)에 도입되었습니다.
답변3
sort
이는 만병통치약이 아니며 데이터가 도착하기 전에 다른 적절한 도구를 사용하여 데이터를 필터링해야 합니다 sort
. tail
일을 해야 합니다. 예를 들어, 마지막 100개 행을 정렬하려면 다음을 수행합니다.
tail -100 /var/log/foo.log | sort
답변4
파일의 일부만 정렬하려면 sed
다음을 사용할 수 있습니다.
행 15000부터 25000까지 정렬:
sed -n '15000,25000p' | sort
정렬된 파일을 유지하려는 경우에도 이를 고려할 수 있습니다 split
.
사람을 보기 위해 split
.