Para uma lista simples de endereços IPv4, um simples cut
deve ser suficiente:
cut -d "." -f -2 tmp_exim | sort -u
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.
Para uma lista simples de endereços IPv4, um simples cut
deve ser suficiente:
cut -d "." -f -2 tmp_exim | sort -u
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.