host
在运行IP 命令后,我试图确定域+TLD 是否存在于列表中。
我的脚本如下所示:
while read ip; do
PTR=$(host $ip | rev | cut -d" " -f1 | rev | sed 's/\.$//')
if grep -q "$PTR" list.txt
then
echo "Match in list"
else
echo "No match in list"
fi
done <ips.txt
遗嘱内容list.txt
包括:
dns.google
shodan.io
如果我运行 8.8.8.8 的脚本,它会返回谷歌域名该脚本按预期工作。如果我为 198.20.99.130 运行它,它将失败(不匹配),因为结果是人口普查4.shodan.io。
有什么办法可以让我参加grep
比赛仅有的域名+TLD(在本例中为 shodan.io)是否在列表中?
尽管人口普查4.shodan.io应该匹配 list.txt,一个像这样的域shodan.io.example.net不应该。
答案1
您现有的命令失败,因为它执行部分正则表达式而不是完整字符串匹配。它也会非常慢并且不可移植。
改为这样做:
< ips.txt xargs -n 1 host |
awk '
NR==FNR { list[$0]; next }
{
n = split($NF,f,/[.]/)
domtld = f[n-2] "." f[n-1]
print (domtld in list ? "Match" : "No match"), "in list"
}
' list.txt -
Match in list
Match in list
与带有一堆管道到各种其他命令的 shell 循环相比,上面的代码运行得更快,更健壮和可移植。它仅用于一次xargs
调用host
1 行内容list.txt
(因此无需编写循环)并将其输出通过管道传输到单个awk
脚本。该awk
脚本list.txt
在启动时读取一次(而不是像循环 + grep 解决方案中的每个域读取一次),将值存储在名为 的数组中list[]
,然后host
一次一行获取输出,隔离域 + tld,并使用哈希查找它是否在数组中list
以打印所需的输出。无需像现有grep
命令那样担心部分匹配或正则表达式元字符 - 一切都只是使用完整的文字字符串。