Di tanto in tanto voglio estrarre gli intervalli CIDR dai miei file di registro di Apache. Questo è facile per intervalli che ricadono sui confini naturali (/ 8, / 16 e / 24) ma non è così facile per altri intervalli come / 17 e / 25.
Esempi:
# 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
Queste regex ignorano gli indirizzi IP che includono zeri iniziali, ad esempio 192.168.001.001
, che non è un problema nei file di registro di Apache ma potrebbe trovarsi in altri file di registro. Le stampanti in particolare sembrano apprezzare gli zeri iniziali. È abbastanza facile aggiungere gli zero opzionali al regex, ma rende tutto un po 'più difficile. Ci deve essere un modo più semplice.
Esiste un modo semplice per selezionare le righe da un file che corrispondono a qualsiasi intervallo CIDR?
Verranno prese in considerazione estensioni regex di fantasia così come strumenti diversi (come awk
o perl
se necessario, ma voglio che sia un one-liner) se semplificano il lavoro. Idealmente, quello che mi piacerebbe è qualcosa di simile
grep "[:CIDR 192.168.128.0/18:]" access_log
Anche uno strumento che converte un intervallo CIDR nella regex appropriata sarebbe OK.
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
o
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
Punti bonus se la tua risposta copre anche IPv6.