我运行以下代码来提取一些 IP 地址并计算它们的唯一性。例如
./my_program | awk '/^10./{a[$1 FS $2]++ } END { for(i in a) print i,a[i]}' > some_file
包含的输出some_file
是这样的,即:
10.12.33.14 34
10.12.33.11 12
10.12.33.16 5
现在我想要的是运行{system("dig +short -x " i)}
并将输出附加到最后一列,以便文件看起来像
10.12.33.14 34 server1.rdns.domain.tld
10.12.33.11 12 server2.rdns.domain.tld
10.12.33.16 5 server3.rdns.domain.tld
我可以一次性完成此操作,然后将输出传输到文本文件吗?
谢谢!
更新1
... END { for(i in a) cmd=sprintf("dig +short -x \"%s\"", $i); cmd | getline type; close(cmd); printf("%s %s %s\n",i,a[i],type);
这就是输出(stderr)的结尾
dig: '.in-addr.arpa.' is not a legal name (unexpected end of input)
这是我在文件中看到的
10.12.33.14 34
更新2:
END { for(i in a) split(i,ip," ")
cmd=sprintf("dig +short -x \"%s\"", ip[1]); cmd | getline type; close(cmd);
printf("%s %s %s %s\n",ip[1],ip[2],a[i],type)
答案1
您可以使用split()
函数拆分 IP/端口组合并获取 IP 以供稍后在dig()
命令中使用。
END {
for(i in a) {
split(i, ip)
cmd=sprintf("dig +short -x \"%s\"", ip[1])
(cmd | getline type) > 0 ? "" : type="notResolved"
printf("%s %s %s\n",i,a[i],type);
close(cmd)
}
}
我添加了一种检查命令状态的方法dig
,并使用?
三元运算符来更新类型的值。对于失败的情况,您可以添加自己的字符串(例如'notResolved'
上面的字符串)并打印结果。
请注意,使用getline()
呼入awk
与使用呼叫不同system()
。该类型cmd | getline var
使用管道,就像cmd
从 shell 运行一样,每次调用都会getline var
从命令中读取一行输出。但该system()
命令无法提供获取内部执行命令的输出的方法。您只能访问从内部运行的命令返回的退出代码。
PS答案部分采纳了有用的评论穆鲁。
答案2
您可以执行以下操作
步骤1:
./my_program | awk '/^10./{a[$1]++ } END { for(i in a) print i,a[i]}' | tee some_file | xargs -I{} dig +short -x {} > some_file2
第2步:
paste <(awk '{print $1}' some_file ) <(awk '{print $1}' some_file2 ) > result
如果您愿意,some_file
您可以删除。some_file2
rm some_file some_file2
答案3
您也可以awk
完全避免使用。有点慢(尽管使用相同数量的 调用dig
)但很可能更具可读性。
while read -r ip count
do
printf "%s %s %s\n" "$ip" "$count" "$(dig +short -x "$ip" | xargs)"
done < ipaddresses.txt