Extraindo resultados de um comando no terminal

3

Extraindo resultados de um comando em um terminal

Eu executei uma nmap scan no meu local network usando este comando:

nmap -sP 192.168.1.*

Quando eu executei esse comando, recebo algo parecido com isto:

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)

Como posso executar esse comando, mas só imprimo os resultados da seguinte forma:

1. Apple (192.168.1.21)
2. Liteon Technology (192.168.1.15)

O que tentei até agora

Até agora, tentei usar grep , mas não está funcionando tão bem quanto eu esperava. Eu só preciso saber como obter os resultados dessa varredura nmap e organizá-la em uma lista com apenas o que está entre o "()" e também o endereço IP.

    
por iamr00t 25.07.2017 / 03:00

3 respostas

6

Você poderia tentar com o comando 'awk' como segue,

nmap -sP 192.168.1.* | awk -F"[)(]" '/^Nmap/{Nmap=$(NF-1); C+=1} /^MAC Address/{print C"."$(NF-1) "("Nmap")" }' 

saída,

1. Apple (192.168.1.21)
2. Liteon Technology (192.168.1.15)

explicações:

  • com o -F do awk aberto, você está dizendo 'awk' que suas entradas estão delimitadas com ( e / ou ) , como o que foi especificado dentro de grupos de delimitadores -F"[)(]"

  • o '/.../{...} /.../{...}' , é o corpo do script do awk, que no seu caso ele só executará primeiro /^Nmap/{Nmap=$(NF-1); C+=1} ou segundo /^MAC Address/{print C"."$(NF-1) "("Nmap")" } ou nenhuma dessas duas partes da condição onde especificamos ser executada apenas se a sequência de caracteres de entrada ou line starts ( ^ , que é a âncora da linha inicial e aponta para o início de uma linha / registro) com os padrões Nmap (ou na segunda parte MAC Address ). qualquer correspondência encontrada irá executar os códigos dentro de suas chaves {...}

o que a primeira parte está fazendo?
Como explicado acima, se a correspondência for encontrada, segure o segundo último campo ( NF apontando o último campo (ou seu número de campos retornando em um registro com base em delims definidos e $NF seu valor) para a variável Nmap com $(NF-1) ; o C+=1 é uma variável de sinalizador de contador que usamos para contar o número de correspondências também no final usando para a lista de IDs na saída

o que a segunda parte está fazendo?
mesmo que acima, mas quando a correspondência for encontrada ^MAC Address , primeiro imprima o contador C valor, imprima um ponto . , a seguir imprima o segundo último campo da linha correspondente e, no final, imprima o valor de 'Nmap' dentro dos paranteces qual é o IP da linha correspondente anterior

    
por 25.07.2017 / 05:27
3

Você pode usar o formato de saída 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
    
por 25.07.2017 / 12:34
3

Usar awk seria o caminho preferido. Nice um forro. Mas só para mostrar outra solução:

#!/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/.*(\(.*\))//")
    fi
    if [[ "$line" =~ ^MAC ]]; then
        COMPANY=$(echo "$line" | sed -e "s/.*(\(.*\))//")
        COUNTER=$((COUNTER+1))
        echo "${COUNTER}. ${COMPANY} (${IP})"
        IP=
        COMPANY=
    fi
done

Explicação dos comandos sed:

O primeiro comando sed extrai o endereço IP das linhas com o formato Nmap scan report for macbook.att.net (192.168.1.21) . O comando sed usa um regex simples (eu deveria ter usado âncoras e classes de caracteres para ter certeza de que estava extraindo um IP) com um grupo de captura. A primeira parte do comando sed (entre o primeiro e o segundo / ) é uma string a ser correspondida, .*(\(.*\)) . O .*( corresponde a qualquer (ou nenhum caractere) seguido por um parêntese aberto. O grupo de captura é o próximo, isso é \(.*\) , que captura qualquer número de caracteres (em um ambiente de produção, isso deve mudar para uma expressão regular que corresponda ao formato de um endereço IP). O final da regex completa é um único ) . A segunda parte do comando sed (entre o segundo e o terceiro / ) é o que a regex é substituída. Nesse caso, apenas indica o que estava no primeiro grupo de captura.

O segundo comando sed é basicamente a mesma coisa, ou seja, "corresponde a string que contém um par de parênteses no final, substitua a string inteira pelo que estava dentro dos parênteses.

O que é complicado é que, quando você não está usando o sinalizador para usar expressões regulares estendidas, ( e ) são literais. Abra e feche parênteses. Eles precisam ser escapados, \( e \) , para indicar que estão sendo usados para agrupamento.

Por fim, a opção -e que uso no comando. Nesse caso, é opcional, já que cada comando sed tem apenas um script / regex para corresponder. É um hábito meu sempre usá-lo.

Sugestão de leitura, man pages regex(3) , regex(7) , às vezes referido como re_format(7) , e o livro O'Reilly "Mastering Regular Expressions" de Jeffrey Friedl.

    
por 25.07.2017 / 05:45