Время от времени я хочу извлекать диапазоны CIDR из моих файлов журналов Apache. Это легко для диапазонов, которые попадают на естественные границы (/ 8, / 16 и / 24), но не так просто для других диапазонов, таких как / 17 и / 25.
Примеры:
# 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
Эти регулярные выражения игнорируют IP-адреса, которые содержат начальные нули, например 192.168.001.001
, что не является проблемой в файлах журнала Apache, но может быть в других файлах журнала. В частности, принтерам нравятся лидирующие нули. Достаточно просто добавить необязательные нули к регулярному выражению, но это только делает все это немного сложнее. Должен быть более легкий путь.
Есть ли простой способ выбрать строки из файла, которые соответствуют любому диапазону CIDR?
Необычные расширения регулярных выражений будут рассматриваться как различные инструменты (например, awk
или, perl
если необходимо, но я хочу, чтобы они были однострочными), если они облегчат работу. В идеале то, что я хотел бы, это что-то вроде
grep "[:CIDR 192.168.128.0/18:]" access_log
Инструмент, который преобразует диапазон CIDR в соответствующее регулярное выражение, также будет в порядке.
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
или
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
Бонусные баллы, если ваш ответ также охватывает IPv6.