Bash 스크립트: 파일에서 고유한 줄 수
상황:
몇 시간 동안 네트워크 캡처를 통해 얻은 IP 주소와 포트가 포함된 대규모 파일(수백만 개의 회선)이 있습니다(한 줄에 하나의 IP/포트).선의 형식은 다음과 같습니다.
ip.ad.dre.ss[:port]
원하는 결과:
로깅 중에 받은 패킷마다 항목이 있어서 중복 주소가 많습니다.나는 이것을 형식의 행으로 줄일 수 있는 일종의 셸 스크립트를 통해 실행할 수 있기를 원합니다.
ip.ad.dre.ss[:port] count
어디에count
특정 주소(및 포트)의 발생 횟수입니다.특별한 작업을 수행할 필요가 없으며, 서로 다른 포트를 서로 다른 주소로 취급합니다.
지금까지 이 명령을 사용하여 로그 파일에서 모든 IP 주소를 지우는 중입니다.
grep -o -E [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(:[0-9]+)? ip_traffic-1.log > ips.txt
그로부터, 나는 꽤 간단한 정규식을 사용하여 내 주소로 보낸 모든 IP 주소를 긁어낼 수 있습니다(나는 상관하지 않습니다).
그런 다음 다음을 사용하여 고유 항목을 추출할 수 있습니다.
sort -u ips.txt > intermediate.txt
어떻게 해서든 줄 수를 정렬로 집계할 수 있는지 모르겠습니다.
사용할 수 있습니다.uniq
정렬된 반복 줄 수를 가져오는 명령:
sort ips.txt | uniq -c
최상위에서 가장 빈번한 결과를 얻으려면(Peter Jaric 덕분):
sort ips.txt | uniq -c | sort -bgr
사용할 수 있는 총 고유 라인 수(즉, 중복 라인을 고려하지 않음)를 계산하기 위해uniq
또는 와크wc
:
sort ips.txt | uniq | wc -l
awk '!seen[$0]++' ips.txt | wc -l
Awk의 배열은 연관성이 있기 때문에 정렬보다 조금 더 빨리 실행될 수 있습니다.
텍스트 파일 생성 중:
$ for i in {1..100000}; do echo $RANDOM; done > random.txt
$ time sort random.txt | uniq | wc -l
31175
real 0m1.193s
user 0m0.701s
sys 0m0.388s
$ time awk '!seen[$0]++' random.txt | wc -l
31175
real 0m0.675s
user 0m0.108s
sys 0m0.171s
이것은 반복되는 라인의 수를 파악하고 가장 빈도가 낮은 라인부터 가장 빈도가 낮은 라인까지 정확하게 인쇄할 수 있는 가장 빠른 방법입니다.
awk '{!seen[$0]++}END{for (i in seen) print seen[i], i}' ips.txt | sort -n
성능에 관심이 없고 기억하기 쉬운 것을 원한다면 다음을 실행하면 됩니다.
sort ips.txt | uniq -c | sort -n
PS:
sort -n 필드를 숫자로 구문 분석합니다. 즉, 카운트를 사용하여 정렬하므로 정확합니다.
언급URL : https://stackoverflow.com/questions/15984414/bash-script-count-unique-lines-in-file
'programing' 카테고리의 다른 글
권한 오류: [Errno 13] 권한이 거부되었습니다. (0) | 2023.05.27 |
---|---|
환경당 Azure web.config (0) | 2023.05.27 |
T-SQL을 사용하여 MD5 해시 문자열 생성 (0) | 2023.05.27 |
배열에서 중복 값을 찾아 반환하는 방법 (0) | 2023.05.27 |
bash : 잘못된 대체 (0) | 2023.05.27 |