각 IP 주소가 로그 파일에 나타나는 횟수


9

다음과 같은 형식의 파일이 있습니다.

$ cat file.txt

27.33.65.2
27.33.65.2
58.161.137.7
121.50.198.5
184.173.187.1
184.173.187.1
184.173.187.1

파일 file.txt을 다음과 같은 형식으로 구문 분석하는 가장 좋은 방법은 무엇입니까?

27.33.65.2: 2
58.161.137.7: 1
121.50.198.5: 1
184.173.187.1: 3

즉, 파일을 반복하고 각 IP 주소가 나타나는 횟수를 계산하고 싶습니다. 나는 이미 sort모든 IP 주소가 순서대로 서로 직접 연결 되도록 실행했습니다 .


개인적 으로이 종류의 파일을 편리한 인근 DB로 가져오고 (내가 가져온 postgres 인스턴스에 임시 테이블을 생성하여) 빠른 SQL 작업을 수행하고 텍스트 파일로 다시 내 보냅니다.
oakad

답변:


23

당신이 찾고있는 uniq -c

그것의 결과가 당신의 취향에 맞지 않는다면, 그것은 쉽게 파싱되고 재 포맷 될 수 있습니다.

예를 들면 다음과 같습니다.

$ uniq -c logfile.txt | awk '{print $2": "$1}'
27.33.65.2: 2
58.161.137.7: 1
121.50.198.5: 1
184.173.187.1: 3

결합 uniq하고 awk나에게 큰 접근 방식이 아닌 것 같습니다 ...
Hauke ​​Laging

3
uniq정렬 된 입력에서만 작동 하기 때문에 (파일의 어떤 행도 아닌 인접한 일치하는 행과 일치합니다).
oakad

1
결과를 uniq로 파이프하기 전에 결과를 정렬해야합니다. 원래 Q를 읽으면 OP는 sort! 를 사용하여 이미 결과를 정렬했음을 나타냅니다 .
slm

2
@HaukeLaging-귀하의 의견에 감사하지만 대부분의 컴퓨터 사용자는 OSX 및 Windows를 뛰어 넘지 않을 것이며, 여전히 대부분의 Unix 사용자는 특정 작업에 지정된 도구를 사용하는 것 이상을 시도하지 않습니다. AWK를 사용하는 것은 희미한 마음을위한 것이 아닙니다. AWK를 사용하여이 기본 작업을 수행하기 위해 수행해야 할 작업과 Glenn의 솔루션에 필요한 사항을 살펴보십시오. 나는 그의 것이 정신적으로 이해하는 더 간단한 해결책이라고 말하는데 공정하다고 생각합니다. BTW, 나는 둘 다 정확하기 때문에 UV를 모두했습니다!
slm

1
@HaukeLaging-그렇습니다. 사이트를 둘러 보면 IMO의 책임이 약간 변경됩니다. 우리는 포괄적 인 A'ers를 만들고 OP와 그 이후의 모든 방문객들에게 다시 IMO를 가르치는 순간으로 제공하는 A'ers를 볼 책임이 있습니다. 그러나 개인적인 선택이므로 몇 분만 여유를 가지면 어떤 형태로든 A를 제공하는 것이 좋습니다.
slm

6

uniq실제로 영리한 해결책 인 것 같습니다. 어색한 방법 :

awk '{ip_count[$0]++}; '\
'END {for (ip in ip_count) printf "%15s: %d\n",ip,ip_count[ip];}' file

+1. 출력 순서가 OP에 중요하다면,이 답변은 보장하지 않습니다. 연관 배열의 키를 반복하는 것이 본질적인 순서는 아닙니다.
glenn jackman

@glennjackman 그러나 sort더 적은 수의 항목을 정렬해야하므로 답변에 추가 하는 것이 여전히 빠릅니다. ;-)
Hauke ​​Laging

오 예? 오 예?!? ;) 입력이 이미 정렬되었습니다. 이 awk 답변은 그것들을 섞습니다. 그래서 여전히 더 많은 일입니다. 냐! ;)
glenn jackman

0

firest sort 파일은 unic -c로 계산됩니다.

sort filename | uniq -c


1
파일은 이미 (질문의 사용자에 따라) 정렬되어 uniq -c작동하지만 잘못된 형식으로 출력을 제공합니다. 이것이 허용 된 답변sort의 출력을 사용하지 않고 대신 다시 포맷하는 이유 입니다 uniq -c.
Kusalananda

감사합니다 @Aeyd. 이 명령을 찾고있었습니다. 그것은하는 데 도움이
user11392987

0

나는 파이썬을 사용할 것이다. 오늘날 모든 리눅스 시스템에는 python2가 설치되어 있습니다.

각 IP 주소를 dict (연관 배열)에 키 = 값 쌍 (예 : { "12.34.56.78": 1, "87.76.43.21": 3})으로 추가하십시오.

IP 주소를 키로 '확인'하고 값을 1 씩 증가시킵니다. defaultdict ( "ip")를 사용하는 경우 키가 존재하지 않으면 기본값 0으로 작성됩니다. 키가 존재하는 경우 이미 defaultdict는 아무것도하지 않습니다. 다음 줄에서 값이 증가합니다.

#!/usr/bin/python2

infile = open("file.txt","r")
iplist = {}  # create an empty dict

for line in infile:
    line = line.strip()   # remove newline.
    if line: # if not a blank line.
        iplist.setdefault(line, 0) # check for ip and add with default value of 0
        iplist[line] += 1 # increment

outfile = open("out.txt","w") #open output file

for key in iplist.keys():
    line = "%-15s = %s" % (key, iplist[key])
    print line   # print uf desired.
    outfile.write(line + "\n")

출력 파일 :

cat out.txt                                                          
27.33.65.2      = 2
58.161.137.7    = 1
121.50.198.5    = 1
184.173.187.1   = 3

나는 당신이 커맨드 라인 솔루션을 찾고 있다는 것을 알고 있지만, 당신이 볼 수 있듯이 그것은 수십 줄 정도의 우아한 형식의 디스플레이입니다. 파이썬은 훌륭한 관리 도구입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.