Encontre a primeira ocorrência de cada um desses padrões, com grep

1

Isto:

cat /var/log/apache2/other_vhosts_access.log |grep -m 1 123.123.123.123

me dá a primeira ocorrência do IP 123.123.123.123.

Mas como obter a 1ª ocorrência de IP1 e a 1ª ocorrência de IP2 e a 1ª ocorrência de IP3 e ...?

Isso obviamente não funciona, mas dá a ideia:

cat /var/log/apache2/other_vhosts_access.log |grep -m 1 123.123.123.123 AND 124.124.124.124 AND 125.125.125.125
    
por Basj 23.06.2017 / 18:24

2 respostas

2

Eu usaria o awk para fazer isso (assumindo que o ip é a primeira coluna):

awk '!seen[$1]++ && $1 ~ /123.123.123.123|124.124.124.124|125.125.125.125/' /var/log/apache2/other_vhosts_access.log
    
por 23.06.2017 / 18:30
1

Observe que grep '123.123.123.123' não fornece a primeira ocorrência do 123.123.123.123 IP , mas do padrão 123.123.123.123 que corresponde a 123.123.123.123 , mas também de 1234123-123e123 como . é o operador de expressão regular que corresponde a qualquer caractere único.

O 123\.123\.123\.123 corresponderia apenas a 123.123.123.123 , mas isso seria 23\.123\.123\.1 . Veja também a opção -F de grep para correspondência de cadeia fixa.

Aqui, eu faria:

awk '
  !ips_seen {ip[$0]; n++; next}
  {
    found = 0
    for (i in ip)
      if (index($0, i)) {
        found = 1
        delete ip[i]
        n--
      }
  }
  found
  !n {exit}' ips.txt ips_seen=1 input.txt

Em que ips.txt contém a lista de endereços IP, um por linha.

Lembre-se de que, se uma linha contiver mais de um IP, ela ainda será impressa apenas uma vez.

Ao usar index() , que apenas procura substrings, nós cuidamos do primeiro problema acima de . correspondendo a qualquer caractere, mas não ao segundo.

    
por 23.06.2017 / 19:10