如何使用“findstr”或其他批处理方法在Windows中匹配IP地址?

3

正如标题所述,我想在Windows中使用批处理匹配IP地址,请告诉我该如何做?
我知道“findstr”可以匹配类似于“[0-9]”的正则表达式,但是如何使“findstr”匹配出现一到三次


好问题。我认为使用findstr不可能实现。您可能需要添加您正在使用的cmd.exe版本。这些工具已经在“最近”得到了相当大的更新。 - 0xC0000022L
STATUS_ACCESS_DENIED: (a) findstr 完全独立于 cmd 版本,毕竟它是一个单独的程序。 (b) 据我所知,自 Windows 2000 以来,cmd 就没有更新过。 - Joey
@Joey - XP和更近期的Windows之间至少有一个FINDSTR的区别:XP的最大搜索字符串长度为127个字节,而更近期的版本支持最多511个字节。我不知道Vista FINDSTR是否适用于XP,反之亦然。 - dbenham
dbenham,这对我来说是新闻(并感谢您提供问题/答案的链接 - 我正在阅读)。 不过,这个限制可能在这里不适用。 - Joey
5个回答

6

findstr的正则表达式支持有点过时,所以你通常不能使用在网上找到的大多数正则表达式。下面的正则表达式匹配由点分隔的四个数字串:

ipconfig | findstr /r "[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*"

然而,如果你只对地址感兴趣而不关心子网掩码,你可能想使用

ipconfig | findstr /r "Address.*[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*"

是的,它也会匹配像 Address: 232345.534.78678.345 这样的东西,但显然这不是一个IP地址。但通常情况下,ipconfig 不会输出这样的字符串。


关于版本,我只是想为自己和朋友写一个小批处理程序,所以我会确保它可以在Win7和XP上运行。感谢您的答复,使用ipconfig确实有效。 - mts
在这两个例子中,搜索模式[0-9]不需要重复(令人困惑),而不会影响功能。 - peet
@peet,有必要避免匹配像 ... 这样的字符串。 - Joey
哇,你说得完全正确,我没有意识到“*”也可以匹配零个字符,我以为至少会匹配一个字符 - 这是不正确的 - 所以我正在收回自己的话,并坚决坚持相反的观点。谢谢解释。 - peet
由于“?”无法使用,ONE需要编写一小段代码,使用“for”循环来验证在至少4个和最多4个由“.”分隔的部分之间,每个部分中至少有1个数字,最多有3个数字,并且在循环内可以验证第一组在“None”和“2”之间,第二组和第三组在“1”和“5”之间!真的没有人做过这个吗? - peet
只是为了准确起见,在“1”和“9”之间的第二个和第三个,同时总体和组合不超过255 - 很有趣。 - peet

3

如果你的findstr命令的输入不应该是ipconfig的结果,那么你可以使用以下代码行在文本或csv文件中查找IP地址。

findstr /r "\<[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\>" filename.txt

它在用户Joey的答案中添加了元字符。在开头加上"\<",在结尾加上">"。即使这样的字符串可能不是很常见(或者很不可能出现),但这确保了不会返回以字母字符开头和/或结尾的类似IP地址格式的字符串(例如A198.252.206.16或198.252.206.16A)。

当你将一个变量设置为IP地址并希望验证它是否在(大致)IP格式中时,这也非常有效。在我的情况下:echo %3 | findstr "your-regex" > %tmp%\tmp.txt 然后 set /p ip<%tmp%\tmp.txt只有当它通过正则表达式时才设置该变量。谢谢! - Loduwijk

2
FINDSTR是唯一一个原生批处理工具,它对正则表达式提供了一定的支持。但是这种支持非常有限且不标准。仅支持*的重复表达式。此外,它仅限于最多15个字符类项(请参见Windows FINDSTR命令的未记录功能和限制是什么?)。因此,我认为不可能开发出一个原生批处理正则表达式来精确匹配IP地址。
您可以使用PowerShell作为本地Windows工具,也可以通过CSCRIPT命令使用JScript或VBScript。这三个工具都具有更好的正则表达式支持。
或者,您可以下载许多Windows版本的Unix实用程序之一,其中许多是免费的。GnuWin32是一个很好的资源(包括grep):http://gnuwin32.sourceforge.net/

谢谢,我从未使用过GNU,可能在有空的时候会试试。 - mts

1

简而言之;

这将属于标题中的“任何其他方法”部分,但我在批处理命令中使用了for循环和findstr来获取所需的IP。在我的情况下,我将IP设置为名为IP的环境变量。

以下是命令:

for /f "tokens=3 delims=: " %i  in ('netsh interface ip show config name^="Ethernet" ^| findstr "IP Address"') do set IP=%i

对于那些好奇想知道这一切意味着什么的人,请继续阅读

例如,大多数使用ipconfig的命令只是打印出您的所有IP地址,而我需要一个特定的IP地址,这在我的情况下是为了我的以太网网络适配器。

您可以使用netsh interface ipv4 show interfaces命令查看您的网络适配器列表。大多数人需要Wi-Fi或以太网。

您将在命令提示符的输出中看到如下表格:

Idx     Met         MTU          State                Name
---  ----------  ----------  ------------  ---------------------------
  1          75  4294967295  connected     Loopback Pseudo-Interface 1
 15          25        1500  connected     Ethernet
 17        5000        1500  connected     vEthernet (Default Switch)
 32          15        1500  connected     vEthernet (DockerNAT)

在名称列中,您应该找到所需的网络适配器(例如以太网、Wi-Fi等)。
如上所述,我对我的情况感兴趣的是以太网。
要获取该适配器的IP地址,我们可以使用netsh命令:
netsh interface ip show config name="Ethernet"
这将给我们以下输出:
Configuration for interface "Ethernet"
    DHCP enabled:                         Yes
    IP Address:                           169.252.27.59
    Subnet Prefix:                        169.252.0.0/16 (mask 255.255.0.0)
    InterfaceMetric:                      25
    DNS servers configured through DHCP:  None
    Register with which suffix:           Primary only
    WINS servers configured through DHCP: None

(出于安全考虑,我伪造了上面的实际IP地址)
我可以使用MS-DOS命令提示符中的findstr命令进一步指定我想要的行。在这里,我想要包含字符串IP地址的行。
netsh interface ip show config name="Ethernet" | findstr "IP Address"

这将产生以下输出:

 IP Address:                           169.252.27.59

我可以使用for命令,对文件(或在这种情况下是多行字符串)进行解析,并根据定界符和我感兴趣的项号分离字符串内容。 请注意,我正在寻找第三项(tokens=3),并且我正在使用空格和:作为我的定界符(delims=: )。
for /f "tokens=3 delims=: " %i  in ('netsh interface ip show config name^="Ethernet" ^| findstr "IP Address"') do set IP=%i

循环中的每个值或标记都被打印为变量%i,但我只对第三个“标记”或项感兴趣(因此tokens=3)。请注意,我必须使用^转义|=

for命令的末尾,您可以指定要运行的命令以返回内容。在这种情况下,我正在使用set将该值分配给名为IP的环境变量。如果您愿意,您也可以仅回显该值或任何您喜欢的内容。

有了这个,您就可以获得一个环境变量,其中包含分配给环境变量的首选网络适配器的IP地址。相当不错,是吗?

如果您有任何改进的想法,请留言。


感谢您提供的出色指导。我需要这个“版本”来从混乱的nmap输出中获取IP,而“for”语法则是救星! - Alz

1
一个简单的正则表达式字符串可能是:

(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.(1?[0-9]?[0-9]|2[0-4][0-9])|25[0-5]

精确匹配允许的IP地址范围。

编辑:根据下面的评论和findstr中的正则表达式信息,修改上述正则表达式为[0-2][0-9][0-9]\.[0-2][0-9][0-9]\.[0-2][0-9][0-9]\.[0-2][0-9][0-9]以匹配IP地址。显然,FINDSTR在正则表达式解释方面确实有限。


这个正则表达式不被FINDSTR(或任何其他本地批处理实用程序)支持。它应该可以在PowerShell、JScript或VBScript中使用。 - dbenham
1
谢谢。我同意FINDSTR在正则表达式解释方面确实非常有限。而且我认为"[0-2][0-9][0-9]"只能匹配从"000"到"299",无法匹配像"10.10.10.10"这样的内容。 - mts
好的想法,但它无法查找不带3个数字的IP地址,例如1.2.3.4 - peet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接