繁体   English   中英

awk 如果不匹配打印“未知”,多个匹配

[英]awk if not matched print “unknown”, multiple matches

我得到了一个 nmap 结果,我正在尝试使用 awk 处理各种(主机启动或关闭)结果。

我正在传递一个 ip 地址,我正在尝试获取以下信息:状态(向上或向下)、主机名、操作系统。
目标:我需要访问每个字段才能使用其值更新数据库。 另外我正在尝试以尽可能简单的方式来实现这一点,也许有任何方法可以将字段保存在变量中,这样我就可以使用它,检查它是否为空等?

更多细节:

  1. 如果主机已关闭 host_name="unknown",并且 OS="unknown"
  2. 如果 Host up 抓取 host_name 并检查 OS -> 这里有两种可能性,/Running:/ 或 /OS guesses/ 两者都会给我们操作系统,但我们将有一个或另一个。

已启动主机的预期 output:

                     $ip              $status     $host_name    $os
when host up:        134.99.120.2     host_up     HostName      Linux
when host down:      134.99.120.2     host_down   unknown       unknown

我在这里想出了一个班轮:
sudo nmap -O -R -p 22 -oN -T4 134.99.120.2 | awk '/down/{print$5}/Nmap scan report/{print$5}/Running:/{print$2}/OS guess/{print$4}'
但这并不提供对 output 的任何控制。

nmap 的原始输出:
主机启动时:

 
> Starting Nmap 6.40 ( http://nmap.org ) at 2020-11-29 14:58 EST
> Nmap scan report for HostName (134.99.120.2) Host is up (0.00067s
> latency). PORT   STATE SERVICE 22/tcp open  ssh Warning: OSScan
> results may be unreliable because we could not find at least 1 open
> and 1 closed port Device type: general purpose Running: Linux OS CPE:
> xx:/o:xxx:xxxxxos:9.10 OS details: Linux Network Distance: 7 hops OS
> detection performed. Please report any incorrect results at
> http://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned
> in 2.58 seconds 

当主机关闭时:

> Starting Nmap 6.40 ( http://nmap.org ) at 2020-11-29 15:00 EST
> Note: Host seems down. If it is really up, but blocking our ping
> probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 3.64
> seconds 

您实际上可以通过将提取的数据设置为 awk 中的变量,然后在 END 块中打印它们,从而根据需要格式化数据,因此:

 sudo nmap -O -R -p 22 -oN -T4  134.99.120.2  | awk -v ip="134.99.120.2" '

 /Host is up/ { 
                 status="host_up" 
              } 
 /Host seems down/ { 
                 status="host_down" 
              } 
 /Nmap scan report/ { 
                 hstname=$5 
              } 
 /Running:/ { 
                 os=$2 
            } 
 /OS guess/ { 
                 os=$4 
            } 
        END { 
                 !os?os="unknown":os=os;
                 !hstname?hstname="unknown":hstname=hstname;
                 printf "%s\t%s\t%s\t%s\n",ip,status,hstname,os 
             }'

一个班轮:

sudo nmap -O -R -p 22 -oN -T4  134.99.120.2 | awk -v ip="134.99.120.2" '/Host is up/ { status="host_up" } /Host seems down/ { status="host_down" } /Nmap scan report/ { hstname=$5 } /Running:/ { os=$2 } /OS guess/ { os=$4 } END { !os?os="unknown":os=os;!hstname?hstname="unknown":hstname=hstname;printf "%s\t%s\t%s\t%s\n",ip,status,hstname,os }'

使用 -F 将变量 ip 传递到 awk 中,然后根据搜索到的文本设置 os、hstname 和 status。 在结束块中,检查是否存在 hstname 和 os 变量。 如果它们不存在,请将变量设置为未知,否则将它们设置为它们已经存在的值。 最后以所需格式打印变量。

注意看起来拉曼在“发布您的答案”按钮上要快一些......

假设:

  • nmap output 将始终类似于 OP 提供的两个示例之一
  • nmap output 将始终在相同字段中包含HostnameOS名称(即,由于数据长度可变,不必担心nmap在不同单词处换行)
  • 虽然 OP 在其示例awk中显示OS guess ,但示例nmap数据显示OS details (答案 - 下面 - 基于OS details ;OP 可以根据他们的nmap调用实际返回的内容进行修改)
  • nmap数据实际上确实在 output 的每一行的第一列中包含一个> (如 OPs 示例输入中所示); 这意味着 OP awk字段引用可能需要相应地移动 +/-(OP 可以调整答案 - 下面 - 基于行是否以>开头)

示例输入(代替在我的主机上运行nmap ):

$ cat nmap.up.dat
> Starting Nmap 6.40 ( http://nmap.org ) at 2020-11-29 14:58 EST
> Nmap scan report for HostName (134.99.120.2) Host is up (0.00067s
> latency). PORT   STATE SERVICE 22/tcp open  ssh Warning: OSScan
> results may be unreliable because we could not find at least 1 open
> and 1 closed port Device type: general purpose Running: Linux OS CPE:
> xx:/o:xxx:xxxxxos:9.10 OS details: Linux Network Distance: 7 hops OS
> detection performed. Please report any incorrect results at
> http://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned
> in 2.58 seconds

$ cat nmap.down.dat
> Starting Nmap 6.40 ( http://nmap.org ) at 2020-11-29 15:00 EST
> Note: Host seems down. If it is really up, but blocking our ping
> probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 3.64
> seconds

一个awk解决方案,尽管我假设 OP 实际上不会有 2 组nmap output 用于单个 ip 地址(???)...

ipaddr='134.99.120.2'

awk -v ip="${ipaddr}" '                                # pass ip addr in as awk variable "ip"
FNR==1            { hstat="host_up"                    # reset defaults for status ...
                    hname=hos="unknown"                # hostname and host OS
                  }
/down/            { hstat="host_down" ; next }         # reset status
/scan report for/ { hname=$6          ; next }         # reset hostname
/OS details/      { hos=$5            ; next }         # reset host OS

ENDFILE           { fmt="%-18s%-12s%-15s%s\n"          # re-usable format
                    if ( NR==FNR )                     # for first file print a header:
                       { printf fmt, "$ip", "$status", "$host_name", "$os" }

                    printf fmt, ip, hstat, hname, hos  # otherwise print results
                  }
' nmap.up.dat nmap.down.dat

注意ENDFILE需要GNU awk (根据 Ed Morton 的评论)

以上生成:

$ip               $status     $host_name     $os
134.99.120.2      host_up     HostName       Linux
134.99.120.2      host_down   unknown        unknown

决定对(简单)令牌分析器进行滑动,该分析器消除了awk中对硬编码字段引用的需要,但仍假设来自nmap的文本 output 与 OPs 示例输出中显示的一样。

示例输入(代替在我的主机上运行nmap ):

$ cat nmap.up.dat
> Starting Nmap 6.40 ( http://nmap.org ) at 2020-11-29 14:58 EST
> Nmap scan report for HostName (134.99.120.2) Host is up (0.00067s
> latency). PORT   STATE SERVICE 22/tcp open  ssh Warning: OSScan
> results may be unreliable because we could not find at least 1 open
> and 1 closed port Device type: general purpose Running: Linux OS CPE:
> xx:/o:xxx:xxxxxos:9.10 OS details: Linux Network Distance: 7 hops OS
> detection performed. Please report any incorrect results at
> http://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned
> in 2.58 seconds

$ cat nmap.down.dat
> Starting Nmap 6.40 ( http://nmap.org ) at 2020-11-29 15:00 EST
> Note: Host seems down. If it is really up, but blocking our ping
> probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 3.64
> seconds

一个用于令牌分析器的awk想法:

ipaddr='134.99.120.2'

awk -v ip="${ipaddr}" '                             # pass ip addr in as awk variable "ip"
FNR==1  { hstat="host_up"                           # reset defaults for status ...
          hname=hos="unknown"                       # hostname and host OS
          prev=""                                   # clear our "prev"ious token
        }

        { for ( i=1 ; i<=NF ; i++ )                 # process each field
              { token=$(i)                          # make note of current token aka field
                if ( token == ">" ) continue        # ignore the ">" in the first column

                # if our "prev"ious token matches any of the case statements then
                # update our variables according to the current token

                switch (prev) {
                    case "scan"           : if ( token == "report") { prev=prev" "token } ; break
                    case "scan report"    : if ( token == "for"   ) { prev=prev" "token } ; break
                    case "scan report for": hname=token             ; prev=token          ; break

                    case "down."          : hstat="host_down"       ; prev=token          ; break
                    case "Running:"       : hos=token               ; prev=token          ; break
                    default               : prev=token                                    ; break
                }
              }
        }
ENDFILE { fmt="%-18s%-12s%-15s%s\n"                 # re-usable format
          if ( NR==FNR )                            # for first file print a header:
             { printf fmt, "$ip", "$status", "$host_name", "$os" }

          printf fmt, ip, hstat, hname, hos         # otherwise print results
        }

' nmap.up.dat nmap.down.dat

注意:ENDFILE 需要 GNU awk

以上生成:

$ip               $status     $host_name     $os
134.99.120.2      host_up     HostName       Linux
134.99.120.2      host_down   unknown        unknown

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM