Bash Script : 파일에서 고유 한 줄 수


129

상태:

몇 시간 네트워크 캡처의 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

어떻게 든 정렬로 줄 수를 집계 할 수 있는지 모르겠습니다.

답변:


303

uniq명령을 사용하여 정렬 된 반복 된 줄 수를 얻을 수 있습니다.

sort ips.txt | uniq -c

가장 자주 결과를 얻으려면 (Peter Jaric 덕분에) :

sort ips.txt | uniq -c | sort -bgr

10
내가 얼마나 좋아 -bgr에 대한 연상 기호처럼 보이는 우연히 bigger우리가 상단에 원하는이다.
dwanderson

1
귀하 .bashrc또는 .bash_aliases파일을 위한 작은 기능으로서 : function countuniquelines () { sort "$1" | uniq -c | sort -bgr; }. 로 전화하십시오 countuniquelines myfile.txt.
Johan

왜 그런지 잘 모르겠습니다 sort -nr.
Nakilon

5

총 고유 라인 수 를 계산 하기 위해 (즉, 중복 라인을 고려하지 않음) 다음 uniq과 함께 또는 Awk를 사용할 수 있습니다 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

흥미 롭군 거대한 데이터 세트에 대해 상당한 차이를 만들 수 있습니다
Wug

1

이것은 반복되는 줄의 수를 얻고 가장 빈번하지 않고 가장 빈번하게 파종되도록 인쇄하는 가장 빠른 방법입니다.

awk '{!seen[$0]++}END{for (i in seen) print seen[i], i}' ips.txt | sort -n

성능에 신경 쓰지 않고 더 쉽게 기억하고 싶다면 다음을 실행하십시오.

sort ips.txt | uniq -c | sort -n

추신:

sort -n 필드를 숫자로 구문 분석합니다. 카운트를 사용하여 정렬하기 때문에 맞습니다.


!의는 {!seen[$0]++}우리가 단지에서 인쇄를하는 것처럼, 여기에 중복입니다 END.
Amir
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.