Bash 按服务和ip筛选输出

Bash 按服务和ip筛选输出,bash,awk,Bash,Awk,我试图解析NMAP输出文件以在终端中显示特定字符串 这就是我到目前为止所做的: #!/bin/bash for y in $(cat out.txt | grep -E 'tcp*open' | awk '{print$2}' | sort | uniq) do echo "$y" for z in $(cat out.txt | grep -E "(([0-9]{1,3}\.){3}[0-9]{1,3} | awk '{print$NF}')

我试图解析NMAP输出文件以在终端中显示特定字符串

这就是我到目前为止所做的:

#!/bin/bash

for y in $(cat out.txt | grep -E 'tcp*open' | awk '{print$2}' | sort | uniq)
do
        echo "$y"
        for z in $(cat out.txt | grep -E "(([0-9]{1,3}\.){3}[0-9]{1,3} | awk '{print$NF}')
              echo "$z"      
        done
done

这行吗?

首先,我试图修改你的代码,但看起来很糟糕。 仅使用bash函数,我会说:

#!/bin/bash

declare -A hash

while read line; do
    if [[ $line =~ ^Nmap\ scan\ report\ for\ ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$ ]]; then
        ip=${BASH_REMATCH[1]}
    elif [[ $line =~ ^[0-9]+/(tcp|udp)\ +[^\ ]+\ +([^\ ]+) ]]; then
        proto=${BASH_REMATCH[2]}
        if [ -x ${hash[$proto]} ]; then
            hash[$proto]=$ip
        else
            hash[$proto]="${hash[$proto]},$ip"
        fi
    fi
done < NMAP_all_hosts.txt

for proto in ${!hash[@]}; do
    echo $proto
    echo ============
    IFS=','
    for ip in ${hash[$proto]}; do
        echo $ip
    done
    echo
done

我不确定是否一定是bash,所以我做了bash和awk:

Awk:-

awk '/Nmap/{ip = $NF}$2 == "open"{type[$NF][i++] = ip}
     END{for(n in type){print n RT "===============";
           for(i in type[n])print type[n][i];print RT}}' input_file
狂欢节:-

#!/usr/bin/env bash

declare -A type

#set -xv
while read -ra array
do
    [[ -z "${array[0]}" ]] && continue

    [[ "${array[0]}" == Nmap ]] && ip=${array[-1]}

    [[ "${array[1]}" == open ]] && type[${array[-1]}]+=" $ip"
done<input_file

for t in "${!type[@]}"
do
    echo -e "$t\\n==============="
    for i in ${type[$t]}
    do
        echo "$i"
    done
    echo ""
done

您不只是要求nmap提供更容易解析的输出格式,这有什么原因吗?它既支持JSON(您可以使用jq查询),也支持XML(您可以使用XPath或XQuery或基于XSLT的工具(例如XMLStarlet)进行查询)。顺便说一句,nmap还支持-oG,这显然是为了便于使用标准shell工具进行解析。当您的实际消费者是脚本时,使用显式用于人类消费的输出格式几乎是站不住脚的。此外,grep | awk几乎总是一种反模式-您可以将正则表达式放入awk表达式本身:awk'/regex/{block}'将只对匹配正则表达式的代码运行block。您还可以使用包含的NSE脚本完成大部分困难的工作。它列出一行中的每个端口,以及打开该端口的IP列表。我想今晚我会扩展它,有选择地在服务名而不是端口号上建立索引。。。