我想使用命令查找包含所有开放端口的 IP 地址列表awk
。
我的 nmap 输出文件是:
# Nmap 7.01 scan initiated Sat Mar 18 06:27:08 2017 as: nmap -oG output.txt -T4 -f -iL iplist.txt
Host: 10.0.0.99 () Status: Up
Host: 10.0.0.99 () Ports: 135/open/tcp//msrpc///, 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds///, 514/filtered/tcp//shell///, 554/open/tcp//rtsp///, 10243/open/tcp//unknown///
Host: 192.168.0.1 () Status: Up
Host: 192.168.0.1 () Ports: 135/open/tcp//msrpc///, 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds///, 10243/open/tcp//unknown///
Host: 192.168.0.101 () Status: Up
Host: 192.168.0.101 () Status: Up
# Nmap done at Sat Mar 18 06:29:02 2017 -- 3 IP addresses (3 hosts up) scanned in 113.19 seconds
预期输出:
10.0.0.99 135
10.0.0.99 139
10.0.0.99 445
10.0.0.99 514
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
输出保存在另一个文件中(例如parse.txt)
答案1
您要求awk
,但是使用 Perl 可以很简单地做到这一点,因为它可以轻松地迭代正则表达式的多个匹配项。
$ 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
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
、端口号和“开放”一词将位于各自的字段中。因此,我们可以迭代一行 ( for(i=1;i<=NF;i++){}
) 的所有字段,如果当前字段是open
,则打印主机名和前一个字段(端口):if($i=="open"){print h,$(i-1)}
。
答案3
我认为我无法在这里清楚地表达我的观点。我想强调的是,我们可以
piggyback
在正则表达式 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