从终端中的命令提取结果
我使用以下命令nmap
对我进行了扫描:local network
nmap -sP 192.168.1.*
当我运行该命令时,我得到类似于以下内容的内容:
Nmap scan report for macbook.att.net (192.168.1.21)
Host is up (0.019s latency).
MAC Address: 71:DF:4B:44:80:F1 (Apple)
Nmap scan report for lenovo.att.net (192.168.1.15)
Host is up (0.045s latency).
MAC Address: 21:EA:7D:84:08:A1 (Liteon Technology)
我如何运行该命令,但只输出如下结果:
1. Apple (192.168.1.21)
2. Liteon Technology (192.168.1.15)
到目前为止我已经尝试过的
到目前为止,我已经尝试过使用grep
,但效果并不如我预期。我只需要知道如何从 nmap 扫描中获取结果并将其组织在一个列表中,其中包含“( )”和 IP 地址之间的内容。
答案1
您可以尝试使用“awk”命令,如下所示,
nmap -sP 192.168.1.* | awk -F"[)(]" '/^Nmap/{Nmap=$(NF-1); C+=1} /^MAC Address/{print C"."$(NF-1) "("Nmap")" }'
输出,
1. Apple (192.168.1.21)
2. Liteon Technology (192.168.1.15)
解释:
当 awk
-F
打开时,您告诉“awk”您的输入是用(
和/或分隔的)
,正如我们在分隔符组中指定的那样-F"[)(]"
这
'/.../{...} /.../{...}'
是 awk 的脚本主体,在您的情况下,它将仅运行第一个/^Nmap/{Nmap=$(NF-1); C+=1}
、第二个/^MAC Address/{print C"."$(NF-1) "("Nmap")" }
或不运行这两个条件部分中的任何一个,我们指定仅当输入字符串或行以模式(或在第二部分中)开头(^
即起始行锚点并指向行/记录的开头)时才运行。任何匹配项都会运行其括号内的代码Nmap
MAC Address
{...}
第一部分在做什么?
如上所述,如果找到匹配,则将倒数第二个字段(NF
指向最后一个字段(或基于定义的定界符的记录中返回的字段数及其$NF
值)值保存到变量Nmap
中$(NF-1)
;这C+=1
是一个计数器标志变量,我们用于计算最后的匹配数,用于输出中的 ID 列表
第二部分在做什么?
与上面相同,但是当找到匹配时^MAC Address
,首先打印计数器C
值,打印一个点.
,接下来打印匹配行的倒数第二个字段,最后打印括号内的“Nmap”值,即上一个匹配行的IP
答案2
您可以使用xml
输出格式:
nmap -n -sP -oX - 192.168.1.0/24 | xmlstarlet sel -t \
-m //host \
-v address/@vendor \
-o ' (' -v 'address[@addrtype="ipv4"]/@addr' -o ')' -n
答案3
使用awk
将是首选方式。不错的一个班轮。但只是为了展示另一个解决方案:
#!/bin/bash
COUNTER=0
IP=
COMPANY=
nmap -sP 192.168.1.* | while read line
do
if [[ "$line" =~ ^Nmap ]]; then
IP=$(echo "$line" | sed -e "s/.*(\(.*\))/\1/")
fi
if [[ "$line" =~ ^MAC ]]; then
COMPANY=$(echo "$line" | sed -e "s/.*(\(.*\))/\1/")
COUNTER=$((COUNTER+1))
echo "${COUNTER}. ${COMPANY} (${IP})"
IP=
COMPANY=
fi
done
sed命令解释:
第一个 sed 命令从格式为 的行中提取 IP 地址Nmap scan report for macbook.att.net (192.168.1.21)
。 sed 命令使用一个有点简单的正则表达式(我还应该使用锚点和字符类来确保我提取的是 IP)和捕获组。 sed 命令的第一部分(第一个和第二个之间/
)是要匹配的字符串.*(\(.*\))
。匹配.*(
任何(或不匹配任何字符)后跟一个左括号。接下来是捕获组,它\(.*\)
捕获任意数量的字符(在生产环境中,这应该更改为与 IP 地址格式匹配的正则表达式)。完整正则表达式的末尾是一个)
. sed 命令的第二部分(第二部分和第三部分之间/
)是正则表达式被替换的部分。在本例中,仅\1
指示第一个捕获组中的内容。
第二个 sed 命令基本上是相同的,也就是说“匹配末尾包含一组括号的字符串,用括号内的内容替换整个字符串。
棘手的是,当您不使用标志来使用扩展正则表达式时, and(
是)
文字。打开和关闭括号。它们需要被转义,\(
并且\)
,以表明它们被用于分组。
最后,-e
我在命令中使用的选项。在这种情况下,它是可选的,因为每个 sed 命令只有一个脚本/正则表达式要匹配。我总是习惯使用它。
建议阅读、手册页regex(3)
(regex(7)
有时称为 )re_format(7)
以及 Jeffrey Friedl 所著的 O'Reilly 书籍“掌握正则表达式”。