De tempos em tempos, quero fazer um grupamento dos intervalos do CIDR dos meus arquivos de log do Apache. Isso é fácil para intervalos que se enquadram nos limites naturais (/ 8, / 16 e / 24), mas não tão fáceis para outros intervalos, como / 17 e / 25.
Exemplos:
# 192.168.0.0/16: (easy)
grep " 192\.168\." access_log
# 192.168.128.0/17: (more thought required)
grep -E " 192\.168\.(12[89]|1[3-9][0-9]|2[0-5][0-9])\." access_log
# 192.168.0.0/17: (more thought required)
grep -E " 192\.168\.([0-9]|[0-9][0-9]|1[01][0-9]|12[0-7])\." access_log
# 192.168.128.0/18: (straining my brain)
grep -E " 192\.168\.(1[2-8][0-9]|19[01])\." access_log
Esses regexes ignoram endereços IP que incluem zeros à esquerda, como 192.168.001.001
, que não é um problema nos arquivos de log do Apache, mas poderiam estar em outros arquivos de log. Impressoras, em particular, parecem gostar dos zeros à esquerda. É fácil adicionar os zeros opcionais à regex, mas isso torna a coisa toda um pouco mais difícil. Tem que haver um jeito mais fácil.
Existe uma maneira fácil de selecionar linhas de um arquivo que corresponda a qualquer intervalo do CIDR?
Extensões de regex extravagantes serão consideradas, assim como ferramentas diferentes (como awk
ou perl
, se necessário, mas eu quero que seja uma de uma linha) se elas facilitarem o trabalho. Idealmente, o que eu gostaria é algo como
grep "[:CIDR 192.168.128.0/18:]" access_log
Uma ferramenta que converte um intervalo CIDR no regex apropriado também seria OK.
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
ou
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
Pontos de bônus se sua resposta também abrange o IPv6.