Oprócz poprawnej odpowiedzi Adama Davisa , chciałbym zamieścić własne rozwiązanie dla tej operacji.
Ponieważ lista jest duża, istnieją trzy z wielu różnych sprawdzonych rozwiązań ...
Najpierw przygotuj swoją listę TLD w ten sposób:
wget -O - https://publicsuffix.org/list/public_suffix_list.dat |
grep '^[^/]' |
tac > tld-list.txt
Uwaga: tac
odwróci listę, aby zapewnić .co.uk
wcześniejsze przetestowanie .uk
.
posix wersja powłoki
splitDom() {
local tld
while read tld;do
[ -z "${1##*.$tld}" ] &&
printf "%s : %s\n" $tld ${1%.$tld} && return
done <tld-list.txt
}
Testy:
splitDom super.duper.domain.co.uk
co.uk : super.duper.domain
splitDom super.duper.domain.com
com : super.duper.domain
Aby zmniejszyć rozwidlenia (uniknąć myvar=$(function..)
składni), wolę ustawiać zmienne zamiast zrzucać dane wyjściowe na standardowe wyjście, w funkcjach 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
}
Następnie:
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")
Przy takim samym przygotowaniu:
declare -A TLDS='()'
while read tld ;do
if [ "${tld##*.}" = "$tld" ];then
TLDS[${tld##*.}]+="$tld"
else
TLDS[${tld##*.}]+="$tld|"
fi
done <tld-list.txt
Ten krok jest znacznie wolniejszy, ale splitDom
funkcja będzie znacznie szybsza:
shopt -s extglob
splitDom() {
local domsub=${1%%.*(${TLDS[${1##*.}]%\|})}
local -n result=${2:-domsplit}
result=(${1#$domsub.} $domsub)
}
Testy na moim raspberry-pi:
Obie grzmotnąć skrypty zostały przetestowane z:
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
posixwersja została przetestowana ze szczegółową for
pętlą, ale
Wszystkie skrypty testowe generują te same dane wyjściowe:
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
Pełny skrypt zawierający odczyt pliku i splitDom
pętlę zajmuje ~ 2m z wersją posix, ~ 1m29s z pierwszym skryptem bash opartym na $tlds
tablicy, ale ~22s
z ostatnim skryptem bash opartym na $TLDS
tablicy asocjacyjnej .
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
Więc jeśli wypełnianie tablicy asocjacyjnej jest trudniejsze, splitDom
funkcja staje się dużo szybsza!