How to get all IP addresses from connected devices with specific device name?

Solution 1:

This is a bit complicated but here's the final product

nmap -sn 192.168.1.* | gawk 'match($0, /Nmap scan report for (.*) \((([0-9]{1,3}\.?){4})\)/, a) {print a[2]}'

Here's how it all works

The nmap command

nmap -sn -192.168.1.*
The asterisk works like you expect a wild card should. The output from that command will look something like this

Starting Nmap 7.80 ( https://nmap.org ) at 2021-11-18 09:41 MST
Nmap scan report for _gateway (192.168.1.1)
Host is up (0.024s latency).
Nmap scan report for pixel-5.lan (192.168.1.35)
Host is up (0.14s latency).
Nmap scan report for users-mbp-3.lan (192.168.1.23)
Host is up (0.16s latency).
Nmap scan report for brwa8a795cdb114.lan (192.168.1.44)
Host is up (0.015s latency).
Nmap scan report for iphone.lan (192.168.86.19)
Host is up (0.16s latency).
Nmap done: 256 IP addresses (5 hosts up) scanned in 8.46 seconds

I got this command from this ServerFault post

The gawk command

Gawk is basically awk. It lets you use this match function which has the form
match(string, /regex/, output_variable)
The output variable is an array where the 0th element is the string that was just processed and the rest of the elements are from capture groups. So a simpler example would be:
nmap -sn 192.168.1.* | gawk 'match($0, /Nmap scan report for (.*)/, a) {print a[1]}
This would print

_gateway (192.168.1.1)
pixel-5.lan (192.168.1.35)
users-mbp-3.lan (192.168.1.23)
brwa8a795cdb114.lan (192.168.1.44)
iphone.lan (192.168.1.19)

Here's the gawk documentation. It has reference to match if you want to read up on it.

The regex

Nmap scan report for (.*) \((([0-9]{1,3}\.?){4})\)
Let's break this down.

Nmap scan report for (.*) : This part will match, and pull out the "pixel-5.lan" parts.

[0-9]{1,3}\.?: This matches one to three digits then matches a period if it's there. So it would match "192." or "19" etc.

([0-9]{1,3}\.?){4}: This should match an IP address. It matches [0-9]{1,3}\.? four times. So it looks for 1-3 digits with an optional period, four times. That means that it will also match like 1921681.1 but nmap is going to properly format ip addresses so that's not actually an issue.

\((([0-9]{1,3}\.?){4})\): Now we wrap all the IP stuff up in a capture group and literal parenthesis. The way capture groups are numbered is in the order they are first found. So when we have nested capture groups, the outermost capture group is numbered first.

Nmap scan report for (.*) \((([0-9]{1,3}\.?){4})\): Finally we put everything together. It's important to note that the name is going to be the first capture group, the IP is going to be the second capture group, and the parts of the IP are going to come after that.