Выполните синтаксический анализ выходного файла nmap для печати списка IP-адресов со всеми открытыми портами с помощью awk

Альтернативный подход awk :

$ awk 'NR == 1{printf "%s", $0;next}{printf " %s\n%s", $1,$0}' input.txt                                    
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

Это работает просто: первая строка - это особый случай - мы печатаем ее без новой строки и говорим awk перейти к следующей строке без выполнения других блоков кода . После этого NR == 1 {printf "% s", $ 0; next} пропускается, но другие части выполняют работу.

Помните, что до сих пор мы печатали отформатированную строку без символа новой строки. Таким образом, то, что делает printf "% s \ n% s", $ 1, $ 0 , теперь распечатывает первое слово (и поскольку не было новой строки, оно остается в той же строке вывода) , вставлена ​​новая строка, а затем вся строка (но не заканчивается символом новой строки). Таким образом, следующее первое вставленное слово останется в той же строке. Процесс продолжается и продолжается, пока мы не дойдем до конца файла.

Возможное улучшение - включение блока END {print ""} для вставки последней строки новой строки. В некоторых случаях, когда полученный файл должен обрабатываться другими скриптами, это может быть желательно.


Хотя пользователь специально запросил AWK, тот же подход с печатью форматированных строк может быть применен с другими языками, например Python. Альтернатива Python предоставлена ​​для тех, кому интересно, как это может быть реализовано на других языках:

#!/usr/bin/env python
from __future__ import print_function
import sys

old = None
for index,line in enumerate(sys.stdin):
    if index == 0:
        print(line.strip(),end=" ")
        continue
    words = line.strip().split()
    print(words[0] + "\n" + line.strip(),end=" ")

И использование примерно так:

$ ./append_first.py < input.txt                            
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

Здесь применима та же идея о последней строке новой строки.

1
30.03.2017, 13:11
3 ответа

Подход awk:

$ awk -F'[/ ]' '{h=$2; for(i=1;i<=NF;i++){if($i=="open"){print h,$(i-1)}}}' file 
10.0.0.99 135
10.0.0.99 139
10.0.0.99 445
10.0.0.99 554
10.0.0.99 10243
192.168.0.1 135
192.168.0.1 139
192.168.0.1 445
192.168.0.1 10243

Команда -F[/ ] устанавливает разделитель поля ввода на / или пробел. Это означает, что IP хоста будет $2, а номер порта и слово "open" будут находиться в своих собственных полях. Поэтому мы можем перебрать все поля строки (for(i=1;i<=NF;i++){}) и, если текущее поле open, вывести имя хоста и предыдущее поле (порт): if($i=="open"){print h,$(i-1)}.

2
27.01.2020, 23:19

Вы просили awk, но это легко сделать с помощью Perl, поскольку он позволяет легко перебирать несколько совпадений regex.

$ perl -ne '$host = $1 if /^Host: (\S+)/; while(m,(\d+)/open,g) 
    { print "$host\t$1\n" } ' < nmap.out 
10.0.0.99       135
10.0.0.99       139
...


perl -ne                       # Run the code for each input line
'$host = $1 if /^Host: (\S+)/  # If the line starts with "Host: ", 
                               # save the next non-whitespace string
while( m,(\d+)/open,g ) {      # Go through all matches of `<digits>/open`
                               # on the line, catching the digits
    print "$host\t$1\n"        # Print the saved hostname and the matched digits.
}'                              
2
27.01.2020, 23:19

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

perl -lne '
    /^
        Host: \s+ (\S+) \s+         # stuff $1 with hostname
        .+?:                        # seek the nearest colon :
        (?:                         # setup a loop
           \s+(\d+)\/open\/\S+      # this pattern should repeat
           (?{ print "$1\t$2" })    # print hostname+digits foreach turn
        )* # (?{ CODE }) does a code execution during regex search
    /x;
' yourfile
0
27.01.2020, 23:19

Теги

Похожие вопросы