【问题标题】:Sort hosts file by TLD domain, not by suffix (.com.whatever) or prefix (subdomains)按 T​​LD 域排序主机文件,而不是按后缀 (.com.whatever) 或前缀(子域)
【发布时间】:2017-08-15 04:07:06
【问题描述】:

我需要对主机文件中的超大半密耳条目列表进行排序。但我不想按子域或 .com .net 对它们进行排序。

所以这个:

www.apple3.com
this.apple4.com
that.apple1.uk
and.that.apple2.com.br

会变成这样:

that.apple1.uk
and.that.apple2.com.br
www.apple3.com
this.apple4.com

此列表中还没有 ips(因为所有将解析为 0.0.0.0,我稍后会添加)只是域在列表中。我正在使用带有 brew 的 Mac,所以我可以使用任何 GNU 或 nix 工具。提前致谢!

【问题讨论】:

  • 所以apple2.com.br 是一个子域?您使用什么规则来决定域名的子域部分是什么?
  • IO::Socket::SSL 模块的最新版本包括IO::Socket::SSL::PublicSuffix,您可以使用它来获取公共后缀(即com.br)或根域(上一级,即@ 987654326@) 到域。一旦你有了这个,你就可以按这个排序。该模块的文档包含有关如何访问根域的示例。

标签: perl sorting unix terminal


【解决方案1】:

在 Perl 中高效排序的关键是创建一个函数,将要排序的值转换为可以按字典顺序排序的代表性字符串。

例如,如果要对日期进行排序,可以将它们转换为 yyyymmdd 格式。在这种情况下,我们将重新排序域的各个部分,以便

foo.bar.apple1.co.uk

成为以下之一:

# Using this approach, the sorted order of apple1.com and apple1.net will vary.
apple1.bar.foo

# Using this approach, the sorted order of apple1.com and apple1.net will be consistent.
apple1.bar.foo<NUL>uk.co

我们希望数字自然排序(1、2、10 而不是 1、10、2)。我们的关键函数可以处理这个问题,但我们将通过将sort 替换为Sort::Key::Natural 中的natkeysort 来采取简单的方法。作为奖励,natkeysort 允许我们轻松集成我们的关键功能!

困难的部分是识别后缀。没有规则,只是不断变化的定义。因此,我们将使用一个模块来识别后缀。


使用Domain::PublicSuffix实现按键功能:

use feature qw( state );

use Domain::PublicSuffix qw( );

sub get_sort_key {
   my ($host) = @_;
   $host =~ s/\.\z//;
   state $dps = Domain::PublicSuffix->new();
   $dps->get_root_domain($host)
      or die "$host: ".$dps->error();

   my @name   = split /\./, substr($host, 0, -length($dps->suffix())-1);
   my @suffix = split /\./, $dps->suffix();
   return join('.', reverse @name)."\0".join('.', reverse @suffix);
}

使用IO::Socket::SSL::PublicSuffix实现按键功能:

use feature qw( state );

use IO::Socket::SSL::PublicSuffix qw( );

sub get_sort_key {
   my ($host) = @_;
   my @host = split(/\./, $host);
   state $ps = IO::Socket::SSL::PublicSuffix->default();
   my ($name, $suffix) = $ps->public_suffix(\@host);
   return join('.', reverse @$name)."\0".join('.', reverse @$suffix);
}

以上函数使用如下:

use feature qw( say );

use Sort::Key::Natural qw( natkeysort );

my @hosts = (
   'www.apple3.net',
   'www.apple3.com',
   'this.apple4.com',
   'that.apple4.com',
   'www.apple10.com',
   'that.apple1.uk',
   'and.that.apple2.com.br',
);

my @sorted_hosts = natkeysort { get_sort_key($_) } @hosts;

say for @sorted_hosts;

输出:

that.apple1.uk
and.that.apple2.com.br
www.apple3.com
www.apple3.net
that.apple4.com
this.apple4.com
www.apple10.com

IO::Socket::SSL::PublicSuffix 应该比Domain::PublicSuffix(和Mozilla::PublicSuffix)更频繁地更新,但它是更大发行版的一部分。

【讨论】:

  • 太棒了!谢谢池上。该脚本抱怨大约 2 个域无效,有些域无效,但很容易编辑掉。最后,PublicSuffix 对我很有帮助。对提供广告垃圾邮件垃圾软件和其他不受欢迎的“商品”的 450k 域进行了排序。我现在将检查所有这些以查看还活着的并编译最终列表。谢谢!
猜你喜欢
  • 2021-04-30
  • 1970-01-01
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 2021-07-15
  • 1970-01-01
  • 2013-08-08
相关资源
最近更新 更多