首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用虚拟IP地址替换不匹配IP地址的字符串?

如何用虚拟IP地址替换不匹配IP地址的字符串?
EN

Unix & Linux用户
提问于 2021-06-24 21:27:52
回答 5查看 1.4K关注 0票数 3

我有一个带有IP地址列表的文件,但是有些字符串不是IP地址,我想用一个虚拟IP地址替换这些字符串。

我使用这个grep搜索IP,但不知道如何用虚拟IP地址替换不匹配的IP地址。我相信这可以用sed来完成。我试过很少的东西,但都没有用。

代码语言:javascript
复制
cat file.txt | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

我有这个sed来匹配文件中的IP地址,但是我不知道如何用虚拟IP替换非IP地址。

代码语言:javascript
复制
sed -rn '/([0-9]{1,3}\.){3}[0-9]{1,3}/p' file.txt

输入:

代码语言:javascript
复制
192.168.10.20
00 03
10.28.214.5
192.168.10.40
BF
192.168.10.50

期望产出:

代码语言:javascript
复制
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

谢谢!

EN

回答 5

Unix & Linux用户

回答已采纳

发布于 2021-06-25 11:04:41

下面的答案使用awk并解决了一个事实,即一个有效的IPv4地址不仅仅是最多3位数字的4个元组,还包括对小于256个数字的约束:

代码语言:javascript
复制
awk -v dummy="192.168.0.0" -F'.' 'NF!=4 {$0=dummy}
    NF==4 {for (i=1;i<=4;i++) {if ( !($i~/^[0-9]{1,3}$/) || $i>255) {$0=dummy;break}}} 1' input.txt

这将指定虚拟IP为变量dummy。然后它将把.作为字段分隔符,并检查是否

  • 一共有四个字段,
  • 如果每个字段仅由1-3位数字组成,则生成的数字小于256。

如果没有满足任何条件,请用虚拟IP替换行。处理后,打印行(包括所做的任何修改)。

请注意,您建议的RegExp不仅可以接受大于255个的字节字段,而且由于缺少锚定,而且只有一个子字符串恰好匹配“4个1-3位数字的数字,用句点分隔”。

票数 2
EN

Unix & Linux用户

发布于 2021-06-25 01:15:29

您的regexp将匹配 IPv4虚线地址--四位地址,但看起来与它们相似(例如,256.256.256.256 --看起来很像IPv4地址,但不是)。

要只匹配有效的 IPv4地址,需要使用以下正则表达式:

代码语言:javascript
复制
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

或者(没有?:非捕获组修饰符):

代码语言:javascript
复制
((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

这需要正确地锚定,例如^$,两端的\b,或者\<\>

见:正则表达式烹饪本,由Jan Goyvaerts和Steven,由O‘’Reilly媒体公司出版。

例如:

代码语言:javascript
复制
$ sed -E '/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/!s/.*/192.168.0.0/' file.txt 
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50
代码语言:javascript
复制
$ perl -p -e 's/.*/192.168.0.0/ unless m/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/' file.txt 
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

这两种方法都将整个输入行更改为192.168.0.0,除非该行匹配有效的IPv4地址。

就我个人而言,我将使用perl的雷杰普::公共模块,它是用于常见模式匹配任务的一个大型正则表达式集合,可以方便地在名为%RE的散列中使用。

代码语言:javascript
复制
$ perl -MRegexp::Common -p -e 's/.*/192.168.0.0/ unless m/^$RE{net}{IPv4}$/' file.txt 
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50
票数 7
EN

Unix & Linux用户

发布于 2021-06-24 22:15:38

NOTE:其他人指出,您为IPv4地址选择的正则表达式存在缺陷。我不打算在这里讨论这个问题,因为它在其他地方有很好的介绍。

您可以在与RE、ex不匹配的行上使用sed的<#>change命令。

代码语言:javascript
复制
$ sed -r '/([0-9]{1,3}\.){3}[0-9]{1,3}/!c\
192.168.0.0
' file.txt
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

使用GNU,您可以简化为

代码语言:javascript
复制
sed -r '/([0-9]{1,3}\.){3}[0-9]{1,3}/!c192.168.0.0' file.txt
票数 6
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/655726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档