我有一个名为的文件hostlist.txt
,其中包含如下文本:
host1.mydomain.com
host2.mydomain.com
anotherhost
www.mydomain.com
login.mydomain.com
somehost
host3.mydomain.com
我有以下小脚本:
#!/usr/local/bin/bash
while read host; do
dig +search @ns1.mydomain.com $host ALL \
| sed -n '/;; ANSWER SECTION:/{n;p;}';
done <hostlist.txt \
| gawk '{print $1","$NF}' >fqdn-ip.csv
哪个输出到fqdn-ip.csv
:
host1.mydomain.com.,10.0.0.1
host2.mydomain.com.,10.0.0.2
anotherhost.internal.mydomain.com.,10.0.0.11
www.mydomain.com.,10.0.0.10
login.mydomain.com.,10.0.0.12
somehost.internal.mydomain.com.,10.0.0.13
host3.mydomain.com.,10.0.0.3
我的问题是如何删除.
逗号之前的没有再次调用sed
还是gawk
?我可以在现有的sed
或调用中执行一个步骤来gawk
删除点吗?
hostlist.txt
将包含 1000 个主机,因此我希望我的脚本快速高效。
答案1
命令sed
、awk
命令以及删除尾随句点都可以组合成一个 awk 命令:
while read -r host; do dig +search "$host" ALL; done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
或者,分布在多行上:
while read -r host
do
dig +search "$host" ALL
done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
因为awk
命令跟在done
语句后面,所以只awk
调用一个进程。尽管效率在这里可能并不重要,但这比在每个循环中创建新的 sed 或 awk 进程更有效。
例子
有了这个测试文件:
$ cat hostlist.txt
www.google.com
fd-fp3.wg1.b.yahoo.com
该命令产生:
$ while read -r host; do dig +search "$host" ALL; done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
www.google.com, 216.58.193.196
fd-fp3.wg1.b.yahoo.com, 206.190.36.45
怎么运行的
awk 一次隐式读取其输入一条记录(行)。此 awk 脚本使用单个变量 ,f
它表示前一行是否是答案部分标题。
f{sub(/.$/,"",$1); print $1", "$NF; f=0}
如果前一行是答案部分标题,
f
则将为 true,并执行花括号中的命令。第一个从第一个字段中删除尾随句点。第二个打印第一个字段,然后是,
,最后一个字段。第三条语句重置f
为零(假)。换句话说,
f
这里起到逻辑条件的作用。f
如果非零(在 awk 中表示“true”),则执行大括号中的命令。/ANSWER SECTION/{f=1}
如果当前行包含字符串
ANSWER SECTION
,则该变量f
设置为1
(true)。这里,
/ANSWER SECTION/
充当逻辑条件。如果当前值与正则表达式匹配,则其值为 trueANSWER SECTION
。如果是,则执行花括号中的命令。
答案2
dig
可以读入包含主机名列表的文件并一一处理它们。您还可以告诉dig
抑制除答案部分之外的所有输出。
这应该会给你你想要的输出:
dig -f hostlist.txt +noall +answer +search |
awk '{sub(/\.$/,"",$1); print $1","$5}'
awk
的sub()
函数用于.
从第一个字段末尾去除文字句点。然后awk
打印字段 1 和 5,并用逗号分隔。
注意:hostlist.txt
未解析的条目将被完全丢弃 - 它们不会出现在 stdout 或 stderr 上。
(在 Linux 和 FreeBSD 上测试)
答案3
将您的调用更改gawk
为以下内容:
| gawk '{print substr($1,1,length($1)-1)","$NF}' >fqdn-ip.csv