Thỉnh thoảng tôi muốn grep CIDR ra khỏi các tệp nhật ký Apache của tôi. Điều này dễ dàng cho các phạm vi nằm trên ranh giới tự nhiên (/ 8, / 16 và / 24) nhưng không dễ dàng cho các phạm vi khác như / 17 và / 25.
Ví dụ:
# 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
Các regex này bỏ qua các địa chỉ IP bao gồm các số 0 đứng đầu, chẳng hạn như 192.168.001.001
, đây không phải là vấn đề trong các tệp nhật ký Apache nhưng có thể nằm trong các tệp nhật ký khác. Máy in đặc biệt có vẻ thích các số 0 hàng đầu. Thật dễ dàng để thêm các số 0 tùy chọn vào regex nhưng nó chỉ làm cho toàn bộ điều này trở nên khó khăn hơn một chút. Cần phải có một cách dễ dàng hơn.
Có cách nào dễ dàng để chọn các dòng từ một tệp phù hợp với bất kỳ phạm vi CIDR nào không?
Các tiện ích mở rộng regex lạ mắt sẽ được coi là các công cụ khác nhau (chẳng hạn như awk
hoặc perl
nếu cần nhưng tôi muốn nó là một công cụ một lớp) nếu chúng làm cho công việc dễ dàng hơn. Lý tưởng nhất, những gì tôi muốn là một cái gì đó như
grep "[:CIDR 192.168.128.0/18:]" access_log
Một công cụ chuyển đổi phạm vi CIDR thành regex thích hợp cũng sẽ ổn.
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
hoặc là
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
Điểm thưởng nếu câu trả lời của bạn cũng bao gồm IPv6.