Usando o grep para encontrar os dois primeiros números de endereços IP?

0

Estou tentando descobrir como usar o grep para extrair apenas os dois primeiros números de um endereço IP em uma lista. Eu tenho uma rotina que está isolando o log entires (do Exim) que eu preciso, agora eu só preciso determinar quais são os dois primeiros números de endereço IP.

Eu tentei isso:

unique_ips2=$(grep "$email" tmp_exim|grep -oE "[0-9]{1,3}\.[0-9]{1,3}"|sort -u)

Mas em vez de apenas obter os dois primeiros números em um conjunto de 4 IPs, isso está me dando 8 pares de números, ou seja, os dois primeiros e os dois últimos de cada IP.

A declaração original usa sed para extrair os IPs completos, assim:

unique_ips=$(grep "$email" tmp_exim|sed 's/.*[[]\([0-9\.]*\)[]].*//'|sort -u|wc -l)

Mas eu não tenho nenhuma familiaridade com sed , e não tenho idéia de como modificar essa declaração, pois cada tentativa só causou erros.

    
por jols 28.02.2014 / 08:59

2 respostas

2

Para uma lista simples de endereços IPv4, um simples cut deve ser suficiente:

cut -d "." -f -2 tmp_exim | sort -u

    
por 28.02.2014 / 09:11
1

Os arquivos de log do Exim contêm muitos dados em cada linha. Continuando com a abordagem do OP para separar as informações de IP, considere:

unique_ips2=$(grep "$email" tmp_exim | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.' | sort -u)

A primeira mudança acima é colocar o regex dentro de aspas simples para que o bash não mexa nele. A segunda mudança está escapando do período. Sem escape, período significa qualquer caractere, mas queremos que signifique apenas um período literal. A terceira mudança é adicionar um período (literal) no final da regex. Isso impede que o regex corresponda aos dois últimos números de um endereço IP.

sed também pode fazer isso bem:

unique_ips2=$(sed -nr "/$email/"' s/.*\[([0-9]{1,3}\.[0-9]{1,3})\..*//p' tmp_exim | sort -u)

A opção -n diz ao sed para não imprimir nada, a menos que nós solicitemos explicitamente a ele e -r , por conveniência, usar o regex estendido. (O OSX é diferente: substitua -r por -E .) A expressão /$email/ indica sed para operar apenas nas linhas que possuem esse endereço de email. (Ao usar sed , grep é muitas vezes supérfluo.) A carne do comando é a substituição s/.*\[([0-9]{1,3}\.[0-9]{1,3})\..*//p . Isso procura por qualquer texto ( .* ) seguido por um colchete literal aberto (em meus registros de exim, o endereço IP é sempre precedido por um colchete aberto) seguido por um número, um período, outro número, um período e, em seguida, qualquer coisa ( .* ). O regex numérico do número de período é agrupado entre parênteses. Isso significa que podemos nos referir a ele como (é o único agrupamento de parentes, então também é o primeiro). Assim, o comando substituto substitui a linha inteira apenas pelos dois primeiros números do endereço IP. O% final% co_de no comando informa p para imprimir o resultado se a substituição ocorrer.

    
por 28.02.2014 / 09:12