![如何从子域列表中 grep 主域](https://linux22.com/image/220156/%E5%A6%82%E4%BD%95%E4%BB%8E%E5%AD%90%E5%9F%9F%E5%88%97%E8%A1%A8%E4%B8%AD%20grep%20%E4%B8%BB%E5%9F%9F.png)
我有一个大文件,其中包含以下形式的域名:
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::PublicSuffix
perl 模块:
$ 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}
以点开头,后跟三个字母字符的组术语
)$
关闭组,锚定到字符串末尾