Od czasu do czasu chcę grep zakresy CIDR poza moimi plikami dziennika Apache. Jest to łatwe w przypadku zakresów, które mieszczą się na naturalnych granicach (/ 8, / 16 i / 24), ale nie jest tak łatwe w przypadku innych zakresów, takich jak / 17 i / 25.
Przykłady:
# 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
Te wyrażenia regularne ignorują adresy IP zawierające początkowe zera, np. 192.168.001.001
Co nie jest problemem w plikach dziennika Apache, ale może znajdować się w innych plikach dziennika. Wydaje się, że drukarki szczególnie lubią zera na początku. Łatwo jest dodać opcjonalne zera do wyrażenia regularnego, ale to sprawia, że całość jest nieco trudniejsza. Musi być prostszy sposób.
Czy istnieje prosty sposób na wybranie linii z pliku pasującego do dowolnego zakresu CIDR?
Fantazyjne rozszerzenia wyrażenia regularnego będą brane pod uwagę, podobnie jak różne narzędzia (takie jak awk
lub w perl
razie potrzeby, ale chcę, aby były one jednowierszowe), jeśli ułatwią to zadanie. Idealnie chciałbym coś takiego
grep "[:CIDR 192.168.128.0/18:]" access_log
Narzędzie, które konwertuje zakres CIDR do odpowiedniego wyrażenia regularnego, również byłoby OK.
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
lub
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
Punkty bonusowe, jeśli Twoja odpowiedź obejmuje również IPv6.