我需要在主机文件中对超级巨大的半密码条目列表进行排序。但我想不是通过子域或.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工具。提前谢谢!
答案 0 :(得分:3)
在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::Key::Natural替换sort
与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
据推测,{p> IO::Socket::SSL::PublicSuffix的更新频率高于Domain::PublicSuffix(和Mozilla::PublicSuffix),但它是较大发行版的一部分。