linux - grep nmap 输出,有条件地打印选定的行

标签 linux bash grep nmap

我正在尝试编写一个 bash 脚本,该脚本将读取 .txt 文件中的一系列 ip 地址,并将使用 NSE ( smb-os-discovery ) 脚本对每个 ip 执行 nmap 扫描。从这个输出中,我只想打印某些行,但前提是其中一行与特定模式匹配。

我已经尝试了多种不同的选项,但无法让它按我想要的方式工作,因为我要检查和输出的两个项目位于不同的两行中。 我最接近的是编写以下 bash 脚本:

#!/bin/bash
for server in $(cat servers-smb.txt); do
nmap --script smb-os-discovery $server | grep "report\|OS: Windows"
done

当运行上面的脚本时,输出有运行 Windows 的服务器,还有那些没有运行 Windows 的服务器的 report 行,这是预期的,因为 grep 表达式包含一个“OR”运算符。

如有任何帮助,我们将不胜感激。

最佳答案

grep 不容易适应您想要的,但 Awk 是天作之合。

#!/bin/sh
while read server; do
   nmap --script smb-os-discovery "$server" |
    awk '/report/ { r=$0 } /OS: Windows/ { print r; print; exit }'
done <servers-smb.txt

Awk 脚本收集报告行,然后将其与 OS: 行一起打印(如果它匹配“OS: Windows”)。

还要注意更改的 shebang(此脚本中没有任何特定于 Bash 的内容,因此不妨使用普通 sh 运行它),while 优先于 + Useless cat ,在循环内正确引用 "$server",最后在控制 block 内使用适当的缩进以提高易读性。

一种不太吸引人的方法是串接两个 grep。我在这里提到它是为了完整性——任何超过一个 grep 的东西最好作为 Awk 或 sed 脚本来完成。

grep "report\|OS: Windows" | grep -B1 "OS: Windows"

最后,使用 grep 实现相同结果的一种简单方法是将 IP 地址添加到输出中,因为您已经在 server 变量中拥有它。

while read server; do
    nmap --script smb-os-discovery "$server" |
    # XXX: suboptimal; see below
    grep "OS: Windows" | sed "s/^/$server:/"
done <servers-smb.txt

当然,grep | sed 也是一种反模式,最好将其表示为 sed 脚本:

while read server; do
    nmap --script smb-os-discovery "$server" |
    sed -n "/OS: Windows/s/^/$server:/p"
done <servers-smb.txt

这具有在一条线上收集一台主机的输出的额外好处,这使其更适合使用典型的 Unix 面向行的工具进行额外处理。

关于linux - grep nmap 输出,有条件地打印选定的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28081830/

相关文章:

linux - 从变量中删除空格

python - 使用 shell=True w/list 时忽略 subprocess.call() 参数

shell - AWK 脚本以及循环和 if 条件

git - 如何在 Git 历史记录中 grep(搜索)已提交的代码

linux - 运行和测试 UVC 小工具

linux - C++/Linux : Using c++11 atomic to avoid partial read on dual-mapped mmap region

BASH:使用 tr 将一行分隔成单词

regex - 使用先行正则表达式替换文本

sql-server - SQL Server 2016标准版linux安装

bash - 多行 bash 注释礼仪 (#+)