nslookup awk 到显示“answer”的文件

nslookup awk 到显示“answer”的文件

我当前正在运行一个脚本,该脚本在一堆主机上使用 nslookup,然后使用 awk 将所需的行打印到表中。我将一行打印到 file1,另一行打印到 file2,然后用于paste file1 file2 >> file3生成此表。

桌子看起来像这样

Host   IP
name  10.10.10.10
name  10.10.10.10
name 10.10.10.10

在大多数情况下,这是有效的。但由于某种原因,我的 160 个结果中约有 20 个在左栏中显示“answer:”,而主机名出现在右侧。像这样:

Host IP
answer:  hostname

这是在整个结果中随机出现的,我无法弄清楚,因为 nslookup 在任何地方都没有单词“answer:”,导致脚本意外 awk。

这是我的脚本供参考:

hosts='hosts.list'
filelines=`cat $hosts`

Empty_Containers(){
        truncate -s 0 tmp.txt
        truncate -s 0 file1
        truncate -s 0 file2
}

for h in $filelines ;
do
        Empty_Containers
        nslookup $h > tmp.txt
        if grep -q "NXDOMAIN" tmp.txt
        then
                cat tmp.txt | awk 'FNR ==4 {print$5}' > file1
                echo "Did_Not_Resolve" > file2
                paste file1 file2 >> i.txt
        else
                cat tmp.txt | awk 'FNR ==4 {print$2}' > file1
                cat tmp.txt |awk 'FNR ==5 {print$2}' > file2
                paste file1 file2 >> i.txt
        fi
        cat i.txt | column -t 2 i.txt
done

答案1

如果您期望的目标只是制作一个主机名和 IP 地址表,并且您并不特别关心使用nslookup,那么我似乎能够通过快速for .. echo循环创建您想要的输出:

for h in $( cat hosts.list ); do
    a=$(dig +short $h | head -n1)
    echo -e "$h\t${a:-Did_Not_Resolve}"
done

dig是一个比 is 更易于脚本编写的 DNS 工具nslookup,使用该+short选项可以使输出更加清晰。没有记录的请求的输出是一个空字符串,因此我使用内置的bash默认参数扩展 ( ${var:-default}) 来处理没有记录的情况,给出“默认”答案Did_Not_Resolve

$ dig www.example.com

; <<>> DiG 9.10.6 <<>> www.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23579
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;www.example.com.       IN  A

;; ANSWER SECTION:
www.example.com.    20308   IN  A   93.184.216.34

;; Query time: 28 msec
;; SERVER: 172.28.8.1#53(172.28.8.1)
;; WHEN: Fri Jun 01 12:02:27 MST 2018
;; MSG SIZE  rcvd: 60

$ dig +short www.example.com
93.184.216.34

最终的产量是这样的:

www.example.com 93.184.216.34
www.google.com  172.217.14.68
host.doesnotexist.tld   Did_Not_Resolve
unix.stackexchange.com  151.101.129.69

另一种选择dighost

$ for h in $(cat hosts.list); do host $h; done
www.example.com has address 93.184.216.34
www.example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946
www.google.com has address 216.58.193.196
www.google.com has IPv6 address 2607:f8b0:4007:80d::2004
Host host.doesnotexist.tld not found: 3(NXDOMAIN)
unix.stackexchange.com has address 151.101.129.69
unix.stackexchange.com has address 151.101.1.69
unix.stackexchange.com has address 151.101.65.69
unix.stackexchange.com has address 151.101.193.69

回答以下评论中的问题:

我使用的唯一选项dig+short,它将输出减少为给定主机的 IP 地址,否则为空字符串。我dig在子 shell ( $( dig [...] )) 中运行,因为我捕获其输出并将其分配给变量a(对于“地址”)。我正在dig通过管道传输某些主机的输出head -n1(例如主机unix.stackexchange.com返回多个 IP 地址;为了简单起见,我只获取第一个。

将其拉出到变量中的原因是,我们可以使用简单的参数扩展技巧来提供“未解析”文本来代替空字符串,如本文前面所述。

具体按照声明中的要求进行扩展echo

echo -e "$h\t${a:-Did_Not_Resolve}"
  • 开关-e告诉echo我将使用e景观序列。在这种情况下,我使用的\t是,当与 结合时-e,变成 aTab而不是文字转义t
  • $h正如您所期望的,只是替换为变量 的内容h
  • \t正如前面所解释的,成为一个选项卡。
  • ${a:-Did_Not_Resolve}。啊,这就是神奇的地方。 bash作为过程的一部分,在进行参数扩展时能够进行一些内省。语法${var:-default}扩展到变量的内容var 或者,如果未设置或为 null,则提供的替换(在此示例中为 ;default或在此处的实际用例中为Did_Not_Resolve)。您可以在bash手册页中标有“参数扩展”的部分中找到有关此内容的更多详细信息。

最终结果是在每一行上按以下顺序输出主机名、 aTab以及地址(如果有)或文本Did_Not_Resolve(如果没有)。

相关内容