Quiero extraer la ip que está al lado de (axyz-pc)
. He realizado esta tarea mediante grep
un comando usando expresiones regulares. Pero necesito extraer mediante awk y 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
Registros:
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
La salida debe ser (IP duplicada, no repetida):
36.32.138.106
114.225.87.41
36.32.138.216
37.49.224.14
Respuesta1
No estoy seguro de por qué grep
se atasca, tendrás que explorarlo más a fondo. Sin embargo, no hay necesidad de perlre aquí, algo como esto sería suficiente (al menos para el ejemplo que has proporcionado):
grep -o 'axyz-pc) \[[^]]*' | grep -o '[^[]*$'
Producción:
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
Ahora ordene numéricamente y aplique uniq
:
sort -t. -k1,1n -k2,2n -k3,3n -k4,4n | uniq
Producción:
36.32.138.106
36.32.138.216
37.49.224.14
114.225.87.41
Respuesta2
Si necesita usar sed
, suponiendo que la ip esté entre los primeros corchetes:
sed -n '/axyz-pc/s/[^[]*\[\([0-9.]*\).*/\1/p' x|sort -nr| uniq
Respuesta3
usando awk y diciéndole que los campos están separados con ]
o [
y que solo necesitamos el segundo campo:
awk -F'[][]' '
{uniqoccurences[$2]++;}
END { for (i in uniqoccurences) {
print i ":" uniqoccurences[i]
}
} '
En el ejemplo anterior también imprimo ":n", es decir, el número de apariciones de cada "$2", pero no hay necesidad de hacerlo (en ese caso, simplemente hágalo print i
en el bucle dentro de la END
sección)
La expresión regular: [][]
utiliza la forma en que se tratan las expresiones regulares ]
y [
dentro de una [...]
clase de carácter (a ]
justo después de a [
se trata como un carácter a buscar, y a [
después de la inicial [
(y antes de un cierre ]
) también se trata como un carácter a buscar. Entonces [][]
busca ]
o [
)
De otra manera:
awk -F'[][]' '{ print $2 }' | sort | uniq
Respuesta4
cat in.txt | awk '/SMTP/{print $7}'
me da esto.
[36.32.138.106]:1236
[114.225.87.41]:3823
[36.32.138.216]:1984
[37.49.224.14]:51593
Para el paso final:
cat in.txt | awk '/SMTP/{print $7}' | sed -e 's/\[//; s/\]//; s/:...//'
Editar: Los $7 anteriores no funcionarán porque los dos tipos de líneas tienen diferentes desplazamientos de campo para la dirección IP. Una mejor manera podría ser:
cat in.txt | awk -F "axyz-pc\) \[" '{print $2}' | awk -F"\]" '{print $1}'
Usaríamos "axyz-pc" como delimitador de campo en el primer awk y luego canalizaríamos la salida al segundo awk.
Usar sed en su lugar no sería complicado.