除了Adam Davis's correct answer,我想发布我自己的这个操作的解决方案。
由于列表很大,所以有许多不同的测试解决方案中的三个...
首先以这种方式准备您的 TLD 列表:
wget -O - https://publicsuffix.org/list/public_suffix_list.dat |
grep '^[^/]' |
tac > tld-list.txt
注意:tac 将反转列表以确保测试.co.uk 之前 .uk。
splitDom() {
local tld
while read tld;do
[ -z "${1##*.$tld}" ] &&
printf "%s : %s\n" $tld ${1%.$tld} && return
done <tld-list.txt
}
测试:
splitDom super.duper.domain.co.uk
co.uk : super.duper.domain
splitDom super.duper.domain.com
com : super.duper.domain
为了减少分叉(避免myvar=$(function..) 语法),我更喜欢在 bash 函数中设置变量而不是将输出转储到标准输出:
tlds=($(<tld-list.txt))
splitDom() {
local tld
local -n result=${2:-domsplit}
for tld in ${tlds[@]};do
[ -z "${1##*.$tld}" ] &&
result=($tld ${1%.$tld}) && return
done
}
然后:
splitDom super.duper.domain.co.uk myvar
declare -p myvar
declare -a myvar=([0]="co.uk" [1]="super.duper.domain")
splitDom super.duper.domain.com
declare -p domsplit
declare -a domsplit=([0]="com" [1]="super.duper.domain")
同样的准备,那么:
declare -A TLDS='()'
while read tld ;do
if [ "${tld##*.}" = "$tld" ];then
TLDS[${tld##*.}]+="$tld"
else
TLDS[${tld##*.}]+="$tld|"
fi
done <tld-list.txt
这一步明显慢了很多,但是splitDom函数会变得快很多:
shopt -s extglob
splitDom() {
local domsub=${1%%.*(${TLDS[${1##*.}]%\|})}
local -n result=${2:-domsplit}
result=(${1#$domsub.} $domsub)
}
在我的树莓派上测试:
bash 的两个脚本都经过了测试:
for dom in dom.sub.example.{,{co,adm,com}.}{com,ac,de,uk};do
splitDom $dom myvar
printf "%-40s %-12s %s\n" $dom ${myvar[@]}
done
posix 版本使用 detailed for 循环进行了测试,但是
所有测试脚本产生相同的输出:
dom.sub.example.com com dom.sub.example
dom.sub.example.ac ac dom.sub.example
dom.sub.example.de de dom.sub.example
dom.sub.example.uk uk dom.sub.example
dom.sub.example.co.com co.com dom.sub.example
dom.sub.example.co.ac ac dom.sub.example.co
dom.sub.example.co.de de dom.sub.example.co
dom.sub.example.co.uk co.uk dom.sub.example
dom.sub.example.adm.com com dom.sub.example.adm
dom.sub.example.adm.ac ac dom.sub.example.adm
dom.sub.example.adm.de de dom.sub.example.adm
dom.sub.example.adm.uk uk dom.sub.example.adm
dom.sub.example.com.com com dom.sub.example.com
dom.sub.example.com.ac com.ac dom.sub.example
dom.sub.example.com.de com.de dom.sub.example
dom.sub.example.com.uk uk dom.sub.example.com
包含文件读取和splitDom 循环的完整脚本使用 posix 版本大约需要 2m,使用基于 $tlds 数组的第一个 bash 脚本大约需要 1m29s,但 ~22s 使用基于 $TLDS 的最后一个 bash 脚本 关联数组。
Posix version $tldS (array) $TLDS (associative array)
File read : 0.04164 0.55507 18.65262
Split loop : 114.34360 88.33438 3.38366
Total : 114.34360 88.88945 22.03628
因此,如果填充 关联数组 是一项更艰巨的工作,splitDom 函数会变得更快!