3

    As the title said, I want to match ip address with batch in windows, please tell me how I can do it?
    I see that "findstr" can match with regex like "[0-9]", but how can "findstr" matches it appears one to three times?

Matt
  • 22,721
  • 17
  • 71
  • 112
mts
  • 109
  • 2
  • 3
  • 10
  • Good question. I think it's not possible with `findstr`. You might want to add which version of `cmd.exe` you're using. Those tools have been updated considerably as of "late". – 0xC0000022L Apr 03 '12 at 13:42
  • STATUS_ACCESS_DENIED: (a) `findstr` is completely independent of the `cmd` version, it's a separate program after all. (b) `cmd` hasn't been updated since Windows 2000, as far as I'm aware. – Joey Apr 03 '12 at 13:46
  • @Joey - There is at least one difference between FINDSTR on XP vs more recent Windows: XP has max search string length of 127 bytes, whereas more recent versions support up to 511 bytes. I don't know if Vista FINDSTR would work on XP, or vice versa. – dbenham Apr 03 '12 at 14:17
  • dbenham, that's news to me (and thanks for the link to your question/answer – currently reading). Still, that limitation probably doesn't apply here. – Joey Apr 03 '12 at 14:23

5 Answers5

6

Since findstr's regex support is a bit ... dated, you usually can't use most regexes you find on the web. The following matches four runs of digits, separated by dots:

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

However, if you're only interested in addresses and not the subnet masks, you might want to use

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

And yes, if would also match things like Address: 232345.534.78678.345 which is obviously not an IP address. But usually ipconfig doesn't spit out such strings.

Joey
  • 344,408
  • 85
  • 689
  • 683
  • Thanks. About the version, I just wanna write a little batch for myself and my friend, so I'll just make sure it can work on Win7 and XP. And thanks for your answer, it does work with ipconfig. – mts Apr 05 '12 at 08:04
  • In both examples the search pattern [0-9] is not neccessary to be (confusing) doubled without impact on functionallity. – peet Nov 25 '13 at 22:20
  • @peet, it is necessary to avoid matching a string like `...`. – Joey Nov 26 '13 at 08:04
  • wowww, you are totally right, i did't realize `"*" matches NONE too`, thought it would be at least ONE - which is not true - so i'm eating my own words and absolutely insist the opposite. thanx for Explanation. – peet Nov 26 '13 at 09:59
  • Because "?" does not work, ONE would Need to write a small piece of code `using "for" loops to verify at least 1 number and at max 3 are found for each part between at least 4 and max 4 groups divided by "." and inside the loops one could verify the first Group between "None" and "2", the second and third between "1" and "5"`! Really nobody done this by now? – peet Nov 26 '13 at 10:50
  • just to be precice, the second and third between "1" and "9" while overall and combinded not more then 255 - interesting. – peet Nov 30 '13 at 09:38
3

In case the input of your findstr command should not be the result of ipconfig, you could use the following line of code to look for an ip-address in a text or csv file.

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

It adds to metacharacters to the answer of user Joey. "\<" at the beginning and ">" at the end. Even though such a string might not be very common (or very unlikely to occur) this makes sure that no string in an ip-address-like format but with an alphabetic character at the end and/or the beginning (e.g. A198.252.206.16 or 198.252.206.16A) is returned.

FabMay
  • 31
  • 1
  • This works great also when you set a variable to an IP and want to verify it is in a (roughly) IP format. In my case: `echo %3 | findstr "your-regex" > %tmp%\tmp.txt` then `set /p ip<%tmp%\tmp.txt` Only sets the variable if it passes the regex. Thank you! – Loduwijk Aug 21 '19 at 21:27
2

FINDSTR is the only native batch utility that has any support for regular expressions. But the support is very limited and non-standard. The only repeat expression supported is *. In addition, it is limited to a maximum of 15 character class terms (see What are the undocumented features and limitations of the Windows FINDSTR command?). So I don't think it is possible to develop a native batch regex that will precisely match an IP address.

You could stay within native windows utilities and use Power Shell, or you could use JScript or VBScript via the CSCRIPT command. All three have much better regex support.

Alternatively you could download any of a number of Windows ports of Unix utilities, many of them free. GnuWin32 is a good resource (includes grep): http://gnuwin32.sourceforge.net/

Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
1

tldr;

This would fall under the "any other method" part of the title but I used a for loop in a batch command together with findstr to get my desired IP. In my case I set the IP to an environment variable called IP.

Here is the command:

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

For those who are curious to know what all that means, read on

Most commands using ipconfig for example just print out all your IP addresses and I needed a specific one which in my case was for my Ethernet network adapter.

You can see your list of network adapters by using the netsh interface ipv4 show interfaces command. Most people need Wi-Fi or Ethernet.

You'll see a table like so in the output to the command prompt:

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)

In the name column you should find the network adapter you want (i.e. Ethernet, Wi-Fi etc.).

As mentioned, I was interested in Ethernet in my case.

To get the IP for that adapter we can use the netsh command:

netsh interface ip show config name="Ethernet"

This gives us this output:

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

(I faked the actual IP number above for security reasons )

I can further specify which line I want using the findstr command in the ms-dos command prompt. Here I want the line containing the string IP Address.

netsh interface ip show config name="Ethernet" | findstr "IP Address"

This gives the following output:

 IP Address:                           169.252.27.59

I can then use the for command that allows me to parse files (or multiline strings in this case) and split out the strings' contents based on a delimiter and the item number that I'm interested in.

Note that I am looking for the third item (tokens=3) and that I am using the space character and : as my delimiters (delims=: ).

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

Each value or token in the loop is printed off as the variable %i but I'm only interested in the third "token" or item (hence tokens=3). Note that I had to escape the | and = using a ^

At the end of the for command you can specify a command to run with the content that is returned. In this case I am using set to assign the value to an environment variable called IP. If you want you could also just echo the value or what ever you like.

With that you get an environment variable with the IP Address of your preferred network adapter assigned to an environment variable. Pretty neat, huh?

If you have any ideas for improving please leave a comment.

Community
  • 1
  • 1
Joshua Dyck
  • 2,113
  • 20
  • 25
  • Thanks for the excellent instructions. I needed this 'version' to get an IP out of a mangled nmap output, and the 'for' syntax was a saver! – Alz Mar 15 '23 at 18:20
1

A simplistic regex string would be

(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]

to match exactly the range of allowable IP addresses.

EDIT: Based on comments below and Regular expressions in findstr information, modify the above regex to [0-2][0-9][0-9]\.[0-2][0-9][0-9]\.[0-2][0-9][0-9]\.[0-2][0-9][0-9] to match IP addresses. Apparently FINDSTR really is that limited in regular expression interpretation.

Community
  • 1
  • 1
saluce
  • 13,035
  • 3
  • 50
  • 67
  • This regex is not supported by FINDSTR, (or any other native batch utility). It should work with power shell, JScript, or VBScript. – dbenham Apr 03 '12 at 13:52
  • 1
    Thanks. I agree that FINDSTR is really limited in regular expression interpretation. And I think "[0-2][0-9][0-9]" may just matches from "000" to "299" and it can't match like "10.10.10.10". – mts Apr 05 '12 at 07:51
  • nice thought but it does not find IP's with NOT 3 numbers like `1.2.3.4` – peet Nov 26 '13 at 10:52