2015-01-22 2 views
0

Я пытаюсь написать сценарий bash, который будет считывать ряд IP-адресов в TXT-файле и будет выполнять nmap-сканирование на каждом отдельном ip с помощью сценария NSE (smb-os-discovery) с этим. Из этого вывода я хотел бы напечатать только определенные строки, но только если один из них соответствует определенному шаблону.grep nmap output, условно распечатать выделенные строки

Я пробовал несколько разных опций, но просто не могу заставить его работать так, как я хочу, учитывая, что два элемента, которые я хочу проверить и выводить, находятся в двух разных строках. Ближайшим мне удалось получить, написав был ниже Баш скрипт:

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

При выполнении этого скрипта на выходе имеет серверы под управлением Windows, но и report линию для тех, которые этого не делают, что, как ожидается, поскольку выражение grep содержит оператор OR.

Любая помощь с этим была бы высоко оценена.

+1

Если ваша основная проблема заключается в том, чтобы выработать лучшее выражение 'grep', отправьте примерный вывод из вашей команды' nmap', с которой мы можем работать. –

ответ

4

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 скрипт собирает строку отчета, а затем выводит его вместе с ОС: линия, если она соответствует «ОС: Windows».

Отметим также измененная притон (нет ничего Bash конкретного в этом сценарии, так что, возможно, также запустить его с простым sh), предпочтение while над for + Useless cat, правильное цитирование "$server" внутри цикла, и, наконец, использование правильного углубления внутри блока управления для удобочитаемости.

Менее привлекательным подходом будет строка 2 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.

Смежные вопросы