2017-03-22 1 views
-3

Ich muss eine super große halbe mil Einträge Liste von Domänennamen in einer Host-Datei sortieren. Aber ich möchte sie nicht nach Subdomains oder nach .com .net sortieren.Sortieren Sie Hosts-Datei nach TLD-Domäne, nicht nach Suffix (.com.whatever) oder Präfix (Subdomänen)

So folgt aus:

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

Wird diese wiederum in:

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

Keine ips noch auf dieser Liste (wie alle auf 0.0.0.0 behoben wird, werde ich das später hinzufügen) nur Die Domains sind in der Liste. Ich benutze einen Mac mit Brew, damit ich jedes GNU- oder Nix-Tool verwenden kann. Danke im Voraus!

+1

Also ist 'apple2.com.br' eine Subdomain? Welche Regel verwenden Sie, um zu entscheiden, welcher Unterdomäne-Teil des Domänennamens verwendet wird? –

+3

Aktuelle Versionen des IO :: Socket :: SSL-Moduls enthalten [IO :: Socket :: SSL :: PublicSuffix] (https: // metacpan.org/pod/IO :: Socket :: SSL :: PublicSuffix), mit dem Sie das öffentliche Suffix (zB 'com.br') oder die Root-Domain (eine Ebene höher, zB' apple2.com.br') erhalten können zu einer Domain. Sobald Sie dies haben, können Sie einfach danach sortieren. Die Dokumentation des Moduls enthält ein Beispiel, wie Sie zur Stammdomäne gelangen. –

Antwort

3

Der Schlüssel zur effizienten Sortierung in Perl besteht darin, eine Funktion zu erstellen, die den zu sortierenden Wert in eine repräsentative Zeichenfolge umwandelt, die lexikografisch sortiert werden kann. Wenn Sie beispielsweise Datumsangaben sortieren möchten, können Sie sie in das Format yyyymmdd umwandeln. In diesem Fall werden wir die Teile der Domäne neu anordnen, so dass

foo.bar.apple1.co.uk 

eine der folgenden Aktionen wird:

# 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 

Wir wollen die Zahlen Art zu sein natürlich, (1, 2, 10 und nicht 1, 10, 2). Unsere Schlüsselfunktion könnte damit umgehen, aber wir nehmen den einfachen Ausweg, indem wir sort durch natkeysort von Sort::Key::Natural ersetzen. Als Bonus, natkeysort können wir einfach unsere Schlüsselfunktion integrieren!

Der schwierige Teil ist, das Suffix zu identifizieren. Es gibt keine Regel dafür, nur ständig ändernde Definitionen. Daher verwenden wir ein Modul, um das Suffix zu identifizieren.


die Tastenfunktion implementiert Verwendung 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); 
} 

die Tastenfunktion implementiert Verwendung 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); 
} 

Die obigen Funktionen werden wie folgt verwendet:

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; 

Ausgang:

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 angeblich wird häufiger aktualisiert als Domain::PublicSuffix (und Mozilla::PublicSuffix), aber es Teil eines größeren Distro ist.

+0

GREAT! Danke Ikegami. Das Skript beschwerte sich über 2 Dutzend Domains, die nicht gültig waren, einige waren es, aber das war einfach zu bearbeiten. Am Ende hat mir der PublicSuffix sehr gut gedient. 450k-Domains, die Werbung für Spam-Junkware und andere nicht wünschenswerte Waren anbieten, wurden sortiert. Ich werde jetzt alle überprüfen, um die Lebenden zu sehen und die endgültige Liste zusammenzustellen. VIELEN DANK! –