Lin*_*oob 12 sed awk string shell-script regular-expression
我有一个名为的文件hostlist.txt
,其中包含这样的文本:
host1.mydomain.com
host2.mydomain.com
anotherhost
www.mydomain.com
login.mydomain.com
somehost
host3.mydomain.com
Run Code Online (Sandbox Code Playgroud)
我有以下小脚本:
#!/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
Run Code Online (Sandbox Code Playgroud)
输出到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
Run Code Online (Sandbox Code Playgroud)
我的问题是如何.
在不调用sed
或gawk
再次调用的情况下删除逗号之前的那个?我可以在现有的sed
或gawk
将删除点的调用中执行的步骤吗?
hostlist.txt
将包含 1000 台主机,因此我希望我的脚本快速高效。
Joh*_*024 18
的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}'
Run Code Online (Sandbox Code Playgroud)
或者,分布在多行中:
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}'
Run Code Online (Sandbox Code Playgroud)
因为awk
命令跟在done
语句之后,所以只awk
调用一个进程。尽管效率在这里可能无关紧要,但这比在每个循环中创建一个新的 sed 或 awk 进程更有效。
有了这个测试文件:
$ cat hostlist.txt
www.google.com
fd-fp3.wg1.b.yahoo.com
Run Code Online (Sandbox Code Playgroud)
该命令产生:
$ 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
Run Code Online (Sandbox Code Playgroud)
awk 一次隐式地读取其输入一条记录(行)。此 awk 脚本使用单个变量 ,f
该变量表示前一行是否为答案部分标题。
f{sub(/.$/,"",$1); print $1", "$NF; f=0}
如果前一行是答案部分标题,f
则为真,并执行花括号中的命令。第一个从第一个字段中删除尾随句点。第二个打印第一个字段,然后是,
,然后是最后一个字段。第三个语句重置f
为零(假)。
换句话说,f
此处用作逻辑条件。如果f
非零(在 awk 中表示“真”),则执行花括号中的命令。
/ANSWER SECTION/{f=1}
如果当前行包含 string ANSWER SECTION
,则变量f
设置为1
(true)。
在这里,/ANSWER SECTION/
作为逻辑条件。如果当前匹配正则表达式,则计算结果为真ANSWER SECTION
。如果是,则执行大括号中的命令。
dig
可以读入包含主机名列表的文件并逐一处理它们。您还可以告诉dig
抑制除答案部分以外的所有输出。
这应该给你你想要的输出:
dig -f hostlist.txt +noall +answer +search |
awk '{sub(/\.$/,"",$1); print $1","$5}'
Run Code Online (Sandbox Code Playgroud)
awk
的sub()
函数用于.
从第一个字段的末尾剥离文字句点。然后awk
打印由逗号分隔的字段 1 和 5。
注意:hostlist.txt
未解析的条目将被完全丢弃 - 它们不会出现在 stdout 或 stderr 上。
(在 Linux 和 FreeBSD 上测试)
将您的调用更改gawk
为以下内容:
| gawk '{print substr($1,1,length($1)-1)","$NF}' >fqdn-ip.csv
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4521 次 |
最近记录: |