В дополнение к правильному ответу Адама Дэвиса я хотел бы опубликовать свое собственное решение для этой операции.
Поскольку список довольно большой, есть три из множества различных протестированных решений ...
Сначала подготовьте свой список TLD таким образом:
wget -O - https://publicsuffix.org/list/public_suffix_list.dat |
grep '^[^/]' |
tac > tld-list.txt
Примечание: tac
перевернет список, чтобы гарантировать тестирование .co.uk
перед .uk
.
Posix версия оболочки
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)
}
Тесты на моем raspberry-pi:
Обе трепать скрипты были протестированы с:
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версия была протестирована с подробным 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
цикл, занимает ~ 2 м с версией posix, ~ 1 мин 29 с с первым скриптом bash на основе $tlds
массива, но ~22s
с последним скриптом bash на основе $TLDS
ассоциативного массива .
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
функция станет намного быстрее!