如何从子域列表中 grep 主域

如何从子域列表中 grep 主域

我有一个大文件,其中包含以下形式的域名:

domain.com
sub.domain.com
sub.domain.co.uk
domain.co.uk

我想提取带有顶级域名(例如.com)或带有国家/地区代码顶级域名的主域名(无子域)。

顶级域名始终由 2-3 个字母组成(例如 .com、.net、.gov)

国家/地区代码顶级域名始终为 2 个字母(例如 .uk、.us),位于行尾。

因此,如果输入包含上述列表,则输出应提取:

domain.com
domain.co.uk

我尝试过这个表达:

grep -P '^[^\.]+\.[a-zA-Z]{2,3}\.[a-zA-Z]{2}$

这是我的解释。-P: perl regex ^: 行首[^\.]: 排除点+: 一次或多次\.: 点[a-zA-Z]{2,3}: 两个或三个字母字符(例如 .com、.co)[a-zA-Z]{2}$: 行尾的两个字母字符

我的问题:我得到的输出总是提取:

domain.co.uk

但不是domain.com

domain.com如何使我的正则表达式提取带有或不带有国家/地区代码顶级域名(例如和 )的域名,domain.co.uk但不包含子域(例如sub.domain.co.uk或 )sub.domain.com

答案1

如果您认为顶级后缀可以是.us, .gov.uk, .tas.gov.au, .uk,则唯一有效的方法是对完整列表进行硬编码。

您可以使用Domain::PublicSuffixperl 模块:

$ perl -MDomain::PublicSuffix -lne '
  BEGIN{$s = Domain::PublicSuffix->new}
  print if $_ eq $s->get_root_domain($_)' < your-file
domain.com
domain.co.uk

这里使用模块附带的默认列表,但您也可以给它更新的列表如果需要,请按照其文档进行。

在 Debian 上,可以在libdomain-publicsuffix-perl软件包中找到该模块。

答案2

?尝试使用以下示例将最后一个国家/地区代码 TLD 设为可选。

使用扩展正则表达式

grep -E '^[^.]+\.[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?$'

或 Perl 正则表达式

grep -P '^[^.]+\.[a-zA-Z]{2,3}(?:\.[a-zA-Z]{2})?$'

答案3

grep -E "^[[:alnum:]-]+(([.][[:alpha:]]{2}){2}|[.][[:alpha:]]{3})$"

^[[:alnum:]-]+一个或多个在开始处锚定的域有效字符

(开始总体组,第一个学期如下

([.][[:alpha:]]{2})以点开头,后跟两个字母字符的子组

{2}前一个子组恰好重复两次

|界定上组中的下一项

[.][[:alpha:]]{3}以点开头,后跟三个字母字符的组术语

)$关闭组,锚定到字符串末尾

相关内容