Dari waktu ke waktu saya ingin mengambil rentang CIDR dari file log Apache saya. Ini mudah untuk rentang yang jatuh pada batas alami (/ 8, / 16 dan / 24) tetapi tidak begitu mudah untuk rentang lain seperti / 17 dan / 25.
Contoh:
# 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
Regex ini mengabaikan alamat IP yang menyertakan angka nol di depan, seperti 192.168.001.001
, yang bukan masalah di file log Apache tetapi bisa di file log lainnya. Printer khususnya tampaknya menyukai angka nol terkemuka. Cukup mudah untuk menambahkan nol opsional ke regex tetapi itu hanya membuat semuanya sedikit lebih sulit. Harus ada cara yang lebih mudah.
Apakah ada cara mudah untuk memilih baris dari file yang cocok dengan rentang CIDR?
Ekstensi regex yang mewah akan dianggap sebagai alat yang berbeda (seperti awk
atau perl
jika perlu tetapi saya ingin itu menjadi satu-liner) jika mereka membuat pekerjaan lebih mudah. Idealnya, yang saya sukai adalah sesuatu
grep "[:CIDR 192.168.128.0/18:]" access_log
Alat yang mengubah rentang CIDR menjadi regex yang sesuai juga akan OK.
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
atau
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
Poin bonus jika jawaban Anda juga mencakup IPv6.