Sortieren Sie eine Liste der Domänennamen (FQDNs), beginnend mit tld und arbeitend links

20

Ich suche nach einer Liste von Domain-Namen (eine Webfilter-Whitelist), beginnend mit der TLD und aufwärts. Ich suche alle * nix oder Windows-Tools, die dies leicht tun können, obwohl ein Skript auch in Ordnung wäre.

Also, wenn das die Liste ist, die Sie erhalten

www.activityvillage.co.uk 
ajax.googleapis.com 
akhet.co.uk 
alchemy.l8r.pl 
au.af.mil 
bbc.co.uk 
bensguide.gpo.gov 
chrome.angrybirds.com 
cms.hss.gov 
crl.godaddy.com 
digitalhistory.uh.edu 
digital.library.okstate.edu 
digital.olivesoftware.com

Dies ist, was ich als Ausgabe möchte.

chrome.angrybirds.com 
crl.godaddy.com 
ajax.googleapis.com 
digital.olivesoftware.com 
digital.library.okstate.edu 
digitalhistory.uh.edu 
bensguide.gpo.gov 
cms.hss.gov 
au.af.mil 
alchemy.l8r.pl 
www.activityvillage.co.uk 
akhet.co.uk 
bbc.co.uk

Nur für den Fall, dass Sie sich fragen, warum Squidguard einen Bug / Designfehler hat. Wenn beide www.example.comund example.combeide in einer Liste enthalten sind, wird der example.comEintrag ignoriert und Sie können nur Inhalte von aufrufen www.example.com. Ich habe mehrere große Listen, die bereinigt werden müssen, weil jemand Einträge hinzugefügt hat, ohne vorher nachzuschauen.

Zoredache
quelle
Sollten die comDomains nicht vorher eduin Ihrer sortierten Liste erscheinen?
Sven
9
Ja, ich kann nicht manuell sortieren, deshalb suche ich ein Werkzeug. :)
Zoredache
3
Außerdem ist die Python-Version dort im Vergleich zur Perl-Version gut, da die Sortierung von Pythons auf Listen von Listen funktioniert. Perls Art funktioniert nicht und musste implementiert werden.
Mark Wagner
1
Nebenbei bemerkt, wäre dies viel schwieriger, wenn OP darum gebeten hätte, die Top-Domains gemäß Mozillas öffentlicher Suffix- Liste ( publicsuffix.org ) als einen Block zu behandeln. Ich könnte irgendwann dazu kommen (es wäre schön, es für ein Projekt zu haben), hat jemand anderes Interesse?
Phk

Antworten:

15

Dieses einfache Python-Skript macht, was Sie wollen. In diesem Beispiel benenne ich die Datei domain-sort.py:

#!/usr/bin/env python
from fileinput import input
for y in sorted([x.strip().split('.')[::-1] for x in input()]): print '.'.join(y[::-1])

Um es auszuführen, benutze:

cat file.txt | ./domain-sort.py

Beachten Sie, dass das sieht ein wenig hässliche , da ich dies als mehr oder weniger ein einfacher Einzeiler ich benutzen musste schrieb Slice - Notation von[::-1] wo negativen Werten arbeiten , um eine Kopie der gleichen Liste in umgekehrter Reihenfolge zu machen , anstatt die mehr deklarativen die Verwendung reverse()des Wird auf eine Weise implementiert, die die Kompositionsfähigkeit beeinträchtigt.

Und hier ist eine etwas längere, aber möglicherweise besser lesbare Version, reversed()die einen Iterator zurückgibt. Daher muss sie auch eingebunden werden list(), um den Iterator zu konsumieren und eine Liste zu erstellen:

#!/usr/bin/env python
from fileinput import input
for y in sorted([list(reversed(x.strip().split('.'))) for x in input()]): print '.'.join(list(reversed(y)))

Bei einer Datei mit 1.500 zufällig sortierten Zeilen dauert es ~ 0,02 Sekunden:

Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.02
Maximum resident set size (kbytes): 21632

Bei einer Datei mit 150.000 zufällig sortierten Zeilen dauert es etwas mehr als 3 Sekunden:

Elapsed (wall clock) time (h:mm:ss or m:ss): 0:03.20
Maximum resident set size (kbytes): 180128

Hier ist eine wahrscheinlich besser lesbare Version, die das reverse()und sort()an Ort und Stelle ausführt , aber in der gleichen Zeit ausgeführt wird und tatsächlich etwas mehr Speicher benötigt.

#!/usr/bin/env python
from fileinput import input

data = []
for x in input():
   d = x.strip().split('.')
   d.reverse()
   data.append(d)
data.sort()
for y in data:
   y.reverse()
   print '.'.join(y)

Bei einer Datei mit 1.500 zufällig sortierten Zeilen dauert es ~ 0,02 Sekunden:

Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.02
Maximum resident set size (kbytes): 22096

Bei einer Datei mit 150.000 zufällig sortierten Zeilen dauert es etwas mehr als 3 Sekunden:

Elapsed (wall clock) time (h:mm:ss or m:ss): 0:03.08
Maximum resident set size (kbytes): 219152
aculich
quelle
Ich habe viele Lösungen gern gesehen. Ich akzeptiere die pythonbasierte Antwort hauptsächlich, weil ich sie für viele meiner anderen Skripte verwende. Die anderen Antworten scheinen alle auch zu funktionieren.
Zoredache
1
Wenn jemand zuerst nach Domainnamen sortieren data.sort(key=lambda x: x[1:])
möchte
9

Hier ist ein PowerShell-Skript, das tun sollte, was Sie wollen. Grundsätzlich werden alle TLDs in ein Array geworfen, umgedreht, sortiert, in die ursprüngliche Reihenfolge zurückgeführt und dann in einer anderen Datei gespeichert.

$TLDs = Get-Content .\TLDsToSort-In.txt
$TLDStrings = @();

foreach ($TLD in $TLDs){
    $split = $TLD.split(".")
    [array]::Reverse($split)
    $TLDStrings += ,$split
}

$TLDStrings = $TLDStrings|Sort-Object

foreach ($TLD in $TLDStrings){[array]::Reverse($TLD)}

$TLDStrings | %{[string]::join('.', $_)} | Out-File .\TLDsToSort-Out.txt

Lief es auf 1.500 Datensätzen - dauerte 5 Sekunden auf einem einigermaßen leistungsstarken Desktop.

Mark Henderson
quelle
Es sollte ziemlich einfach sein, dieses Skript in Bash oder eine andere Sprache zu konvertieren.
Mark Henderson
5 Sekunden scheinen für nur 1.500 Zeilen eine lange Zeit zu sein. Meine Python-Implementierung erledigt 1.500 in einem Bruchteil einer Sekunde und 150.000 in etwas mehr als 3 Sekunden. Was macht es in PowerShell wohl so langsam?
ACULICH
Ja, es ist eine lange Zeit. Ich habe keine Ahnung, warum es so lange dauert. Wahrscheinlich, weil Powershell nicht wirklich darauf abzielt, solche Dinge zu tun.
Mark Henderson
7

cat domain.txt | rev | sortieren | rev

user3721740
quelle
Ich denke das würde funktionieren. Ich mag es, wenn die TLD sortiert wird, und das würde das nicht schaffen. Wenn Sie dies verwenden, befinden sich die TLDs in meinem Beispiel in der Reihenfolge (uk, mil, pl, com, edu, gov), da dies eine einfache Sortierung von rechts nach links anstelle der Domänengrenzen ist.
Zoredache
beste Antwort, die ich gesehen habe!
Daniel
1
rev domain.txt|sort|rev
Rich
6

Etwas weniger kryptisch oder zumindest hübscher, Perl:

use warnings;
use strict;

my @lines = <>;
chomp @lines;

@lines =
    map { join ".", reverse split /\./ }
    sort
    map { join ".", reverse split /\./ }
    @lines;

print "$_\n" for @lines;

Dies ist ein einfaches Beispiel für eine Guttman-Rosler-Transformation : Wir konvertieren die Zeilen in die entsprechende sortierbare Form (hier teilen wir den Domänennamen in Punkte auf und kehren die Reihenfolge der Teile um), sortieren sie mit der systemeigenen lexikografischen Sortierung und konvertieren dann die Linien zurück in ihre ursprüngliche Form.

Ilmari Karonen
quelle
6

In Unix-Skripten: umkehren, sortieren und umkehren:

awk -F "." '{for(i=NF; i > 1; i--) printf "%s.", $i; print $1}' file |
  sort |
  awk -F "." '{for(i=NF; i > 1; i--) printf "%s.", $i; print $1}'
jfg956
quelle
Ähnliches gilt für eine einzelne Schleife: awk -F. '{for(i=NF;i>0;i--){printf ".%s",$i};printf "\t%s\n",$0}' file|sort|cut -f2Möglicherweise möchten Sie lokale Hosts zuerst mitgrep \. file | awk ...
Rich am
3

Hier ist es in (kurz und kryptisch) Perl:

#!/usr/bin/perl -w
@d = <>; chomp @d;
for (@d) { $rd{$_} = [ reverse split /\./ ] }
for $d (sort { for $i (0..$#{$rd{$a}}) {
        $i > $#{$rd{$b}} and return 1;
        $rd{$a}[$i] cmp $rd{$b}[$i] or next;
        return $rd{$a}[$i] cmp $rd{$b}[$i];
} } @d) { print "$d\n" }
Mark Wagner
quelle
Haben Sie Timing-Informationen für diese Art? Ich bin gespannt, wie sich dies im Vergleich zu @ Mark-Hendersons PowerShell-Implementierung und meiner Python-Implementierung verhält . Ich habe /usr/bin/time -vfür die verstrichene Zeit und max Speicherstatistiken verwendet.
ACULICH
4
Perl siegt völlig bei der Verschleierung.
Massimo
4
Das Beschreiben eines Perl-Skripts als "kurz und kryptisch" ist überflüssig.
Belmin Fernandez
@aculich, mit Ausnahme des Powershell-Skripts, scheinen alle Optionen in meiner Datei weniger als 0,1 Sekunden in Anspruch zu nehmen.
Zoredache
0
awk -F"." 's="";{for(i=NF;i>0;i--) {if (i<NF) s=s "." $i; else s=$i}; print s}' <<<filename>>> | sort | awk -F"." 's="";{for(i=NF;i>0;i--) {if (i<NF) s=s "." $i; else s=$i}; print s}'

Dies bewirkt, dass jedes in der Domain hinterlegte Feld umgedreht, sortiert und zurückgedreht wird.

Dies sortiert die Domain-Liste, lexikographisch basierend auf jedem Teil des Domain-Namens, von rechts nach links.

Die umgekehrte Lösung ( rev <<<filename>>> | sort | rev; nicht) habe ich ausprobiert.

Mike Rudra
quelle