awk 如果不匹配则打印"unknown",多次匹配
awk if not matched print "unknown", multiple matches
我得到一个 nmap 结果,我正在尝试使用 awk 处理各种(主机启动或关闭)结果。
我正在传递一个 IP 地址,我正在尝试获取以下信息:状态(打开或关闭)、主机名、OS。
目标:我需要访问每个字段才能使用其值更新数据库。此外,我正在尝试以尽可能简单的方式实现这一点,也许有任何方法可以将字段保存在变量中,这样我就可以使用它,检查它是否为空等?
更多详情:
- 如果主机关闭 host_name="未知",并且 OS="未知"
- if Host up 抓住 host_name 并检查 OS -> 这里有两种可能性,/运行:/ 或 /OS 猜测/他们都会给我们 OS,但我们将有一个或另一个。
已启动主机的预期输出:
$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}/Nmap scan report/{print}/Running:/{print}/OS guess/{print}'
但这并不能控制输出。
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=
}
/Running:/ {
os=
}
/OS guess/ {
os=
}
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= } /Running:/ { os= } /OS guess/ { os= } 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 变量是否存在。如果它们不存在,则将变量设置为未知,否则将它们设置为它们已经存在的值。最后按要求的格式打印变量。
注意 看起来 Raman 在 'Post Your Answer' 按钮上快了一点 ...
假设:
nmap
输出将始终像 OP 提供的两个示例之一
nmap
输出将始终在相同字段中具有 Hostname
和 OS
名称(即,不必担心 nmap
在不同位置换行由于数据长度可变的单词)
- 虽然 OP 在他们的样本
awk
中显示 OS guess
,但样本 nmap
数据显示 OS details
(下面的答案基于 OS details
; OP 可以根据他们 nmap
实际调用的内容进行修改 returns)
nmap
数据实际上在每行输出的第一列中包含一个 >
(如 OP 示例输入中所示);这意味着 OPs 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 实际上不会为单个 IP 地址提供 2 组 nmap
输出 (???) ...
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= ; next } # reset hostname
/OS details/ { hos= ; 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
的文本输出如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
想法:
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
我得到一个 nmap 结果,我正在尝试使用 awk 处理各种(主机启动或关闭)结果。
我正在传递一个 IP 地址,我正在尝试获取以下信息:状态(打开或关闭)、主机名、OS。
目标:我需要访问每个字段才能使用其值更新数据库。此外,我正在尝试以尽可能简单的方式实现这一点,也许有任何方法可以将字段保存在变量中,这样我就可以使用它,检查它是否为空等?
更多详情:
- 如果主机关闭 host_name="未知",并且 OS="未知"
- if Host up 抓住 host_name 并检查 OS -> 这里有两种可能性,/运行:/ 或 /OS 猜测/他们都会给我们 OS,但我们将有一个或另一个。
已启动主机的预期输出:
$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}/Nmap scan report/{print}/Running:/{print}/OS guess/{print}'
但这并不能控制输出。
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=
}
/Running:/ {
os=
}
/OS guess/ {
os=
}
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= } /Running:/ { os= } /OS guess/ { os= } 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 变量是否存在。如果它们不存在,则将变量设置为未知,否则将它们设置为它们已经存在的值。最后按要求的格式打印变量。
注意 看起来 Raman 在 'Post Your Answer' 按钮上快了一点 ...
假设:
nmap
输出将始终像 OP 提供的两个示例之一
nmap
输出将始终在相同字段中具有Hostname
和OS
名称(即,不必担心nmap
在不同位置换行由于数据长度可变的单词)- 虽然 OP 在他们的样本
awk
中显示OS guess
,但样本nmap
数据显示OS details
(下面的答案基于OS details
; OP 可以根据他们nmap
实际调用的内容进行修改 returns) nmap
数据实际上在每行输出的第一列中包含一个>
(如 OP 示例输入中所示);这意味着 OPsawk
字段引用可能需要相应地移动 +/-(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 实际上不会为单个 IP 地址提供 2 组 nmap
输出 (???) ...
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= ; next } # reset hostname
/OS details/ { hos= ; 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
的文本输出如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
想法:
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