De temps en temps, je veux grep les plages CIDR hors de mes fichiers journaux Apache. C'est facile pour les plages qui tombent sur les limites naturelles (/ 8, / 16 et / 24) mais pas si facile pour d'autres plages telles que / 17 et / 25.
Exemples:
# 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
Ces expressions régulières ignorent les adresses IP qui incluent des zéros non significatifs, tels que 192.168.001.001
, ce qui n'est pas un problème dans les fichiers journaux Apache, mais pourrait se trouver dans d'autres fichiers journaux. Les imprimantes en particulier semblent aimer les zéros de tête. Il est assez facile d'ajouter les zéros facultatifs à l'expression régulière, mais cela rend tout cela un peu plus difficile. Il doit y avoir un moyen plus simple.
Existe-t-il un moyen facile de sélectionner des lignes d'un fichier qui correspondent à n'importe quelle plage CIDR?
Les extensions de regex sophistiquées seront prises en compte, tout comme différents outils (tels que awk
ou perl
si nécessaire, mais je veux que ce soit une ligne) s'ils facilitent le travail. Idéalement, ce que j'aimerais, c'est quelque chose comme
grep "[:CIDR 192.168.128.0/18:]" access_log
Un outil qui convertit une plage CIDR en l'expression rationnelle appropriée serait également 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
Points bonus si votre réponse couvre également IPv6.