我正在尝试从多个网络生成的列表中提取 IP,并且需要隔离那些不要以0结尾。
例如,在下面的列表中,它有文本、常规 IP 和 IP 范围。我想做的是只获取常规 IP,而不是任何以 0 或子网掩码结尾的 IP:
; Spamhaus DROP List 2016/07/03 - (c) 2016 The Spamhaus Project
; http://www.spamhaus.org/drop/drop.txt
; Last-Modified: Sun, 3 Jul 2016 21:18:32 GMT
; Expires: Sun, 03 Jul 2016 23:26:45 GMT
1.0.1.0/24
223.223.176.0
129.130.100.100
1.160.118.30
如果我跑grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
它给了我:
1.0.1.0
223.223.176.0
129.130.100.100
1.160.118.30
我尝试将正则表达式的最后部分替换为:
grep -Eo '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[^1-255]'
但它不起作用。
我试图尽量减少使用多个管道 grep(或 sed/awk)来加快搜索过程。例如,我希望避免的是:
grep <all IPs from list> | grep -v <all those that end in 0 or subnet>
是否可以在一行中使用 grep/sed/awk 来获取这些 IP?在上面的例子中,结果应该是:
129.130.100.100
1.160.118.30
谢谢
答案1
你可以试试awk
:
$ awk -F . '$NF !~ /^0/' <file
129.130.100.100
答案2
问题原始版本的答案
$ awk -F'[./]' '($4+0) != 0' iplist
129.130.100.100
怎么运行的
-F'[./]'
这将字段分隔符设置为
.
或/
。这样最后一个八位位组将始终是字段 4。($4+0) != 0
如果第四个八位位组是,则此逻辑条件评估为 true不是0. 由于我们没有针对这种情况包含明确的操作,因此 awk 执行默认操作,即打印该行。
我们添加
0
到第四个字段只是为了确保 awk 执行的是数字比较,而不是字符串比较。
答案3
grep -E '^([0-9]{1,3}\.){3}[1-9][0-9]{0,2}$'
[1-9]
检查最后一个八位位组的第一个数字是否非零 - 后面的可选数字意味着您仍然可以匹配后面的零 ( 129.130.100.100
)。
$
确保该行在最后一个八位字节之后结束,因此它不会与任何带有子网掩码的内容匹配。
[^1-255]
由于以下几个原因,您没有做您想做的事:
- 它处理字符,而不是数字:它的意思是“(
1
和之间2
)OR5
OR5
” ^
方法 ”不是在这个范围内”
因此它排除最后一个八位位组以 1、2 或 5 开头的所有内容,并匹配其余的。