programing

Bash 스크립트: 파일에서 고유한 줄 수

skycolor 2023. 5. 27. 09:58
반응형

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

반응형