Extraire des informations via awk et sed

Je veux extraire ip le très prochain à (axyz-pc) . J'ai fait cette tâche par la command grep utilisant regex. Mais j'ai besoin d'extraire awk et 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

Journaux:

 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 sortie devrait être (doublon ip pas répéter):

 36.32.138.106 114.225.87.41 36.32.138.216 37.49.224.14 

Je ne suis pas sûr de la raison pour laquelle grep est bloqué, vous devrez explorer cela plus loin. Cependant, il n'y a pas besoin de perlre ici, quelque chose comme ça ferait (au less pour l'échantillon que vous avez donné):

 grep -o 'axyz-pc) \[[^]]*' | grep -o '[^[]*$' 

Sortie:

 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 

Maintenant sortinger numériquement et appliquer uniq :

 sort -t. -k1,1n -k2,2n -k3,3n -k4,4n | uniq 

Sortie:

 36.32.138.106 36.32.138.216 37.49.224.14 114.225.87.41 

Si vous avez besoin d'utiliser sed , en supposant que l'ip est dans les premiers parenthèses:

 sed -n '/axyz-pc/s/[^[]*\[\([0-9.]*\).*/\1/p' x|sort -nr| uniq 

en utilisant awk, et en disant que les champs sont séparés par ] ou [ et que nous avons juste besoin du 2ème champ:

 awk -F'[][]' ' {uniqoccurences[$2]++;} END { for (i in uniqoccurences) { print i ":" uniqoccurences[i] } } ' 

Dans l'exemple ci-dessus, j'imprime aussi ": n", c'est-à-dire le nombre d'occurrences de chaque "$ 2", mais il n'est pas nécessaire de le faire (dans ce cas,

Le regexp: [][] utilise la méthode regexp treat ] et [ dans une [...] class de caractères (a ] juste après un [ est alors traité comme un caractère à searchr et un [ après le [ et avant une fermeture ] ) est également traité comme un caractère à searchr. Donc [][] search ] ou [ ]

Autrement:

 awk -F'[][]' '{ print $2 }' | sort | uniq 

Quelques options:

  1. GNU grep

     $ grep -oP '\(axyz-pc\) \[\K[^]]+' file | sort | uniq 114.225.87.41 36.32.138.106 36.32.138.216 37.49.224.14 
  2. perl

     $ perl -lne '/\(axyz-pc\) \[([^]]+)/ && ++$seen{$1}<2 && print $1' file 36.32.138.106 114.225.87.41 36.32.138.216 37.49.224.14 
  3. awk

     $ awk -F ') \\[' '{print $2}' file | awk -F '\\]' '!seen[$1]++{print $1}' 36.32.138.106 114.225.87.41 36.32.138.216 37.49.224.14 
  4. sed

     $ sed -n 's/.*(axyz-pc) \[\([^]]*\).*/\1/p' file | sort | uniq 114.225.87.41 36.32.138.106 36.32.138.216 37.49.224.14 
 cat in.txt | awk '/SMTP/{print $7}' 

me donne ça.

 [36.32.138.106]:1236 [114.225.87.41]:3823 [36.32.138.216]:1984 [37.49.224.14]:51593 

Pour la dernière étape:

 cat in.txt | awk '/SMTP/{print $7}' | sed -e 's/\[//; s/\]//; s/:...//' 

Edit: Les 7 $ ci-dessus ne fonctionneront pas car les deux types de lignes ont des décalages de champs différents pour l'adresse IP. Une meilleure façon pourrait être:

 cat in.txt | awk -F "axyz-pc\) \[" '{print $2}' | awk -F"\]" '{print $1}' 

Nous utiliserions "axyz-pc" comme délimiteur de champ dans le premier awk, puis canaliserons la sortie vers le second awk.

Utiliser sed à la place, ne serait pas compliqué.