Von Zeit zu Zeit möchte ich CIDR-Bereiche aus meinen Apache-Protokolldateien herausgreifen. Dies ist einfach für Bereiche, die an die natürlichen Grenzen fallen (/ 8, / 16 und / 24), aber nicht so einfach für andere Bereiche wie / 17 und / 25.
Beispiele:
# 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
Diese regulären Ausdrücke ignorieren IP-Adressen, die führende Nullen enthalten, z. B. 192.168.001.001
was in Apache-Protokolldateien kein Problem darstellt, aber in anderen Protokolldateien enthalten sein kann. Insbesondere Drucker scheinen die führenden Nullen zu mögen. Es ist einfach genug, die optionalen Nullen zum regulären Ausdruck hinzuzufügen, aber es macht das Ganze nur ein bisschen schwieriger. Es muss einen einfacheren Weg geben.
Gibt es eine einfache Möglichkeit, Zeilen aus einer Datei auszuwählen, die einem beliebigen CIDR-Bereich entsprechen?
Ausgefallene Regex-Erweiterungen werden ebenso berücksichtigt wie verschiedene Tools (wie awk
oder perl
falls erforderlich, aber ich möchte, dass es sich um einen Einzeiler handelt), wenn sie die Arbeit erleichtern. Im Idealfall möchte ich so etwas wie
grep "[:CIDR 192.168.128.0/18:]" access_log
Ein Tool, das einen CIDR-Bereich in den entsprechenden regulären Ausdruck konvertiert, ist ebenfalls in Ordnung.
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
oder
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
Bonuspunkte, wenn Ihre Antwort auch IPv6 abdeckt.