为什么要做这个工作?
# grepcidr 5.45.148.0 list.txt
list.txt
5.45.148.0/22
5.45.148.0/24
这行不通?
# grepcidr 5.45.148.23 list.txt
list.txt
5.45.148.0/22
5.45.148.0/24
CentOS7 存储库提供的 grepcidr 2.0
答案1
我承认这grepcidr
可能有一些怪癖和错误,但我的大部分猜测是不正确的。公平地说,这个答案的部分内容也不够了解,但我的目的是指出,如果使用不同的范例来处理语法和输出,即使 v2 也有一些实用性。
grepcidr
几个月前我开始使用一些防火墙脚本,所以我对它的理解还处于初级阶段。但根据我收集的信息,
grepcidr
效果并不完全一样grep
。特别是,迄今为止我的“心理地图”表明 `grepcidr 不会在输入文件中查找包含字符串(或 CIDR 规范)的行,它会在输入文件中查找包含以下内容的行:
是由 CIDR 规范包含。
换句话说,grep 是大海捞针。使用
grepcidr
,您给它一个干草堆,grepcidr 会向您显示干草堆中包含的所有针。这仍然有点松散,但是......
grepcidr
在文件中查找作为命令行搜索规范的子集(可能是不正确的子集)的条目。
考虑这个脚本:
#!/usr/bin/env bash
cat << EOF > list.txt
5.45.148.0/22
5.45.148.0/24
5.45.149.0/24
5.45.150.0/24
5.45.151.0/24
5.45.152.0/24
5.45.151.17
5.45.151.17 5.45.151.18 5.45.151.19
5.45.151.247
5.44.15.17
5.44.1.0/24
5.44.1.15
5.44.1.5
5.44.1.5/32
EOF
grepcidr -V
j=0
echo $((++j)): "Lines containing entries within 5.45.151.17 (/32)"
grepcidr 5.45.151.17 list.txt
echo $((++j)): "Lines containing entries in the same /24 as 5.45.151.17"
grepcidr 5.45.151.17/24 list.txt
echo $((++j)): "Lines that have no entries within 5.45.0.0/16"
grepcidr -v 5.45.0.0/16 list.txt
echo $((++j)): "Lines with entries within 5.45.151.17/31"
grepcidr 5.45.151.17/31 list.txt
输出:
grepcidr 2.0
Copyright (C) 2004 - 2014 Jem E. Berkes <[email protected]>
1: Lines containing entries within 5.45.151.17 (/32)
5.45.151.17
5.45.151.17 5.45.151.18 5.45.151.19
2: Lines containing entries in the same /24 as 5.45.151.17
5.45.151.0/24
5.45.151.17
5.45.151.17 5.45.151.18 5.45.151.19
5.45.151.247
3: Lines that have no entries within 5.45.0.0/16
5.44.15.17
5.44.1.0/24
5.44.1.15
5.44.1.5
5.44.1.5/32
4: Lines with entries within 5.45.151.17/31
5.45.151.17
5.45.151.17 5.45.151.18 5.45.151.19
对于您的具体示例,您询问grepcidr
“此特定 IP 是否显示为该文件中列出的 /32?”不,事实并非如此。如果您问,该 IP 所在的 /24 是否出现在该文件中,那么是的,它出现在两个位置:
# grepcidr 5.45.148.23 list.txt
# grepcidr 5.45.148.23/24 list.txt
5.45.148.0/22
5.45.148.0/24
所以,是的,V3 很可能是对 V2 的改进,是的,当如此多的 Unix 和 Linux 发行版更新他们的软件包存储库时,这将是美好的一天,但这并不是说 V2 毫无用处。人们只需要小心从输出中得出什么结论即可。
更新
添加新-s
标志以允许“草率”CIDR 规范后,看起来是一样的。我的测试用例很可能并不详尽。
1: Lines containing entries within 5.45.151.17 (/32)
5.45.151.17
5.45.151.17 5.45.151.18 5.45.151.19
2: Lines containing entries in the same /24 as 5.45.151.17
5.45.151.0/24
5.45.151.17
5.45.151.17 5.45.151.18 5.45.151.19
5.45.151.247
3: Lines that have no entries within 5.45.0.0/16
5.44.15.17
5.44.1.0/24
5.44.1.15
5.44.1.5
5.44.1.5/32
4: Lines with entries within 5.45.151.17/31
5.45.151.17
5.45.151.17 5.45.151.18 5.45.151.19
FWIW,您的特定测试用例行为在 V3 中没有变化:
# grepcidr -V
grepcidr 3.0
Parts copyright (C) 2004, 2005 Jem E. Berkes <[email protected]>
# grepcidr 5.45.148.23 list.txt
...尽管解决方案确实似乎在@RasoolZiafaty 建议使用该-D
标志中:
# grepcidr -D 5.45.148.23 list.txt
5.45.148.0/22
5.45.148.0/24
我一直困惑的一个问题是为什么 IP 范围不等于明确列出的 IP:
# cat input.txt
5.45.148.3 5.45.148.4 5.45.148.5
5.45.148.3-5.45.148.5
# grepcidr -D 5.45.148.4 input.txt
5.45.148.3 5.45.148.4 5.45.148.5
当前的行为似乎是,如果文件行引用该 IP 作为起点或终点,则命令行上的特定 IP 仅与文件行匹配。例如5.45.148.4
仅在一行上找到,而5.45.148.3
or5.45.148.5
在两行上匹配。
答案2
尝试在命令中使用 -D
grepcidr -D 5.45.148.3 list.txt
-D 解析输入中的 CIDR 范围,如果搜索词与该范围的任何部分匹配,则进行匹配。
答案3
grepcidr
搜索可能位于 CIDR 网络中的 IP 地址。您正尝试在另一个方向使用它(搜索可能包含给定 IP 地址的 CIDR 网络)。
function reversegrepcidr() {
grep "$(
while read; do
echo $1 | grepcidr "$REPLY" &>/dev/null && echo $REPLY
done < <( grep -Eo "[^^\"][0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}" "$2" )
)" "$2";
}
此函数搜索任何看起来像 CIDR 网络的网络,并为每个网络grepcidr
查看其第一个参数是否在该网络中,如果是,则打印该网络。
警告:这可能不适用于所有版本的,并且仅在 GNU 3.4 和2.0grep
上进行了轻微测试。grep
grepcidr