바로 옆에 있는 IP를 추출하고 싶습니다 (axyz-pc)
. 정규식을 사용하는 명령을 통해 이 작업을 수행했습니다 grep
. 하지만 awk와 sed를 통해 추출해야 합니다.
grep -Po '(?<='axyz-pc')[^:]+' logs | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'| sort -nr| uniq -c |sort -nr
로그:
2017-04-11 15:15:00 SMTP connection from (axyz-pc) [36.32.138.106]:1236 I=[10.10.19.36]:25 closed by DROP in ACL
2017-04-11 15:15:01 H=(axyz-pc) [114.225.87.41]:3823 I=[10.10.19.36]:25 rejected EHLO or HELO axyz-pc: HELO/EHLO - HELO on heloblocks Blocklist
2017-04-11 15:15:01 SMTP connection from (axyz-pc) [114.225.87.41]:3823 I=[10.10.19.36]:25 closed by DROP in ACL
2017-04-11 15:15:02 H=(axyz-pc) [36.32.138.216]:1984 I=[10.10.19.36]:25 rejected EHLO or HELO axyz-pc: HELO/EHLO - HELO on heloblocks Blocklist
2017-04-11 15:15:02 SMTP connection from (axyz-pc) [36.32.138.216]:1984 I=[10.10.19.36]:25 closed by DROP in ACL
2017-04-11 15:15:02 H=(axyz-pc) [37.49.224.14]:51593 I=[10.10.19.36]:25 rejected EHLO or HELO axyz-pc: HELO/EHLO - HELO on heloblocks Blocklist
2017-04-11 15:15:02 SMTP connection from (axyz-pc) [37.49.224.14]:51593 I=[10.10.19.36]:25 closed by DROP in ACL
2017-04-11 15:15:02 H=(axyz-pc) [36.32.138.106]:4619 I=[10.10.19.36]:25 rejected EHLO or HELO axyz-pc: HELO/EHLO - HELO on heloblocks Blocklist
출력은 다음과 같아야 합니다(중복 IP는 반복되지 않음).
36.32.138.106
114.225.87.41
36.32.138.216
37.49.224.14
답변1
왜 막히는지 잘 모르겠습니다 grep
. 더 자세히 조사해야 합니다. 그러나 여기에는 perlre가 필요하지 않습니다. 다음과 같이 하면 됩니다(적어도 제공한 샘플의 경우).
grep -o 'axyz-pc) \[[^]]*' | grep -o '[^[]*$'
산출:
36.32.138.106
114.225.87.41
114.225.87.41
36.32.138.216
36.32.138.216
37.49.224.14
37.49.224.14
36.32.138.106
이제 숫자로 정렬하고 적용하십시오 uniq
.
sort -t. -k1,1n -k2,2n -k3,3n -k4,4n | uniq
산출:
36.32.138.106
36.32.138.216
37.49.224.14
114.225.87.41
답변2
를 사용해야 하는 경우 sed
IP가 첫 번째 대괄호 안에 있다고 가정합니다.
sed -n '/axyz-pc/s/[^[]*\[\([0-9.]*\).*/\1/p' x|sort -nr| uniq
답변3
]
awk를 사용하여 필드가 or 로 구분되어 [
있으며 두 번째 필드만 필요하다고 알려줍니다 .
awk -F'[][]' '
{uniqoccurences[$2]++;}
END { for (i in uniqoccurences) {
print i ":" uniqoccurences[i]
}
} '
위의 예에서는 ":n", 즉 각 "$2"의 발생 횟수도 인쇄하지만 그렇게 할 필요는 없습니다. (이 경우 print i
섹션 내의 루프에서 수행하면 됩니다 END
.)
regexp:는 정규 표현식 이 문자 클래스 내에서 [][]
처리하는 방식을 사용하고 있습니다 ( a 바로 뒤의 a 는 찾을 문자로 처리되고 이니셜 뒤 (및 닫는 문자 앞 )도 찾을 문자로 처리됩니다. 그래서 찾 거나 )]
[
[...]
]
[
[
[
]
[][]
]
[
또 다른 방법:
awk -F'[][]' '{ print $2 }' | sort | uniq
답변4
cat in.txt | awk '/SMTP/{print $7}'
나에게 이것을 준다.
[36.32.138.106]:1236
[114.225.87.41]:3823
[36.32.138.216]:1984
[37.49.224.14]:51593
마지막 단계는 다음과 같습니다.
cat in.txt | awk '/SMTP/{print $7}' | sed -e 's/\[//; s/\]//; s/:...//'
편집: 위의 $7은 두 종류의 라인이 IP 주소에 대해 서로 다른 필드 오프셋을 갖기 때문에 작동하지 않습니다. 더 좋은 방법은 다음과 같습니다.
cat in.txt | awk -F "axyz-pc\) \[" '{print $2}' | awk -F"\]" '{print $1}'
첫 번째 awk의 필드 구분 기호로 "axyz-pc"를 사용한 다음 출력을 두 번째 awk로 파이프합니다.
대신 sed를 사용하면 복잡하지 않습니다.