从文件中过滤黑名单域
filter blacklist domains from file
我有两个文件
第一个文件 blacklist.txt 包含
test.example.com
*.test.example.com
第二个文件subdomains.txt包含
test.example.com
123.test.example.com
abc-test.example.com
www.example.com
预期结果文件包含
abc-test.example.com
www.example.com
这是从 subdomains.txt 中过滤黑名单文件中列出的所有子域
如果存在 *.
,它会同时检查正则表达式,然后也会删除所有子域,如预期结果所示。
在我的搜索过程中,我发现以下命令使用 awk 但如果文件 blacklist.txt 中有 *
则不起作用
awk 'NR == FNR { list[tolower([=15=])]=1; next } { if (! list[tolower([=15=])]) print }' blacklist.txt subdomains.txt
但是当它只包含域时它会过滤掉
我也尝试过 comm 命令,但它似乎无法处理正则表达式
如果稍微修改一下黑名单正则表达式:
test\.example\.com
.*\.test\.example\.com
你可以:
$ awk 'NR==FNR {
a[[=11=]];next
}
{
for(i in a)
if(match([=11=],"^" i "$"))
next
print
}' blacklist subdomains
输出:
abc-test.example.com
www.example.com
如果您使用 sed 处理黑名单以将其转换为正则表达式列表,您可以使用:
sed 's/\./\./g;s/\*/.*/g' blacklist.txt |
grep -vixf - subdomains.txt
不需要对黑名单模式进行任何预处理的纯bash
版本:
#!/usr/bin/env bash
readarray -t blacklist < blacklist.txt
while read -r domain; do
match=0
for pat in "${blacklist[@]}"; do
if [[ $domain == $pat ]]; then
match=1
break
fi
done
[[ $match -eq 0 ]] && printf "%s\n" "$domain"
done < subdomains.txt
并且把它放进去,一个 tcl
版本应该比上面的脚本在大文件上更有效:
#!/usr/bin/env tclsh
# Takes two arguments; the blacklist file and the domain file
# e.g.,
# ./domainfilter blacklist.txt subdomains.txt > results.txt
proc ggrep {blacklist domainfile} {
set f [open $domainfile]
set domains [split [read -nonewline $f] \n]
close $f
set f [open $blacklist]
while {[gets $f pattern] >= 0} {
set domains [lsearch -inline -all -not -glob $domains $pattern]
}
close $f
puts [join $domains \n]
}
ggrep [lindex $argv 0] [lindex $argv 1]
也是一个更高效的 zsh
版本,如果 shell 是一个选项:
#!/usr/bin/env zsh
declare -A blacklist
while read -r pattern; do
blacklist[$pattern]=1
done < blacklist.txt
while read -r domain; do
# Treat the array keys as glob patterns matched against index
[[ -z ${blacklist[(k)$domain]} ]] && printf "%s\n" "$domain"
done < subdomains.txt
我有两个文件
第一个文件 blacklist.txt 包含
test.example.com
*.test.example.com
第二个文件subdomains.txt包含
test.example.com
123.test.example.com
abc-test.example.com
www.example.com
预期结果文件包含
abc-test.example.com
www.example.com
这是从 subdomains.txt 中过滤黑名单文件中列出的所有子域
如果存在 *.
,它会同时检查正则表达式,然后也会删除所有子域,如预期结果所示。
在我的搜索过程中,我发现以下命令使用 awk 但如果文件 blacklist.txt 中有 *
则不起作用
awk 'NR == FNR { list[tolower([=15=])]=1; next } { if (! list[tolower([=15=])]) print }' blacklist.txt subdomains.txt
但是当它只包含域时它会过滤掉
我也尝试过 comm 命令,但它似乎无法处理正则表达式
如果稍微修改一下黑名单正则表达式:
test\.example\.com
.*\.test\.example\.com
你可以:
$ awk 'NR==FNR {
a[[=11=]];next
}
{
for(i in a)
if(match([=11=],"^" i "$"))
next
print
}' blacklist subdomains
输出:
abc-test.example.com
www.example.com
如果您使用 sed 处理黑名单以将其转换为正则表达式列表,您可以使用:
sed 's/\./\./g;s/\*/.*/g' blacklist.txt |
grep -vixf - subdomains.txt
不需要对黑名单模式进行任何预处理的纯bash
版本:
#!/usr/bin/env bash
readarray -t blacklist < blacklist.txt
while read -r domain; do
match=0
for pat in "${blacklist[@]}"; do
if [[ $domain == $pat ]]; then
match=1
break
fi
done
[[ $match -eq 0 ]] && printf "%s\n" "$domain"
done < subdomains.txt
并且把它放进去,一个 tcl
版本应该比上面的脚本在大文件上更有效:
#!/usr/bin/env tclsh
# Takes two arguments; the blacklist file and the domain file
# e.g.,
# ./domainfilter blacklist.txt subdomains.txt > results.txt
proc ggrep {blacklist domainfile} {
set f [open $domainfile]
set domains [split [read -nonewline $f] \n]
close $f
set f [open $blacklist]
while {[gets $f pattern] >= 0} {
set domains [lsearch -inline -all -not -glob $domains $pattern]
}
close $f
puts [join $domains \n]
}
ggrep [lindex $argv 0] [lindex $argv 1]
也是一个更高效的 zsh
版本,如果 shell 是一个选项:
#!/usr/bin/env zsh
declare -A blacklist
while read -r pattern; do
blacklist[$pattern]=1
done < blacklist.txt
while read -r domain; do
# Treat the array keys as glob patterns matched against index
[[ -z ${blacklist[(k)$domain]} ]] && printf "%s\n" "$domain"
done < subdomains.txt