Ordina un elenco di nomi di dominio (FQDN) a partire da tld e funzionando a sinistra


20

Sto cercando di ordinare un elenco di nomi di dominio (una whitelist di filtri Web) a partire dal TLD e funzionando verso l'alto. Sto cercando qualsiasi * nix o strumenti di Windows che possano farlo facilmente, anche se uno script andrebbe bene.

Quindi se la è la lista che ti è stata data

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

Questo è quello che voglio come output.

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

Nel caso ti stia chiedendo perché, Squidguard, ha un difetto di bug / design. Se entrambi www.example.come example.comsono entrambi inclusi in un elenco, la example.comvoce viene ignorata e puoi visitare solo il contenuto www.example.com. Ho diversi elenchi di grandi dimensioni che richiedono una certa pulizia perché qualcuno ha aggiunto voci senza prima cercare.


I comdomini non dovrebbero apparire prima edunel tuo elenco ordinato?
Sven

9
Sì, non riesco a smistare manualmente, motivo per cui sto cercando uno strumento. :)
Zoredache,


3
Inoltre, la versione di Python è piacevole rispetto alla versione di Perl perché l'ordinamento di Pythons funziona su liste di liste; il tipo di perl no e doveva essere implementato.
Mark Wagner,

1
Da un lato, ciò sarebbe molto più impegnativo se OP avesse richiesto che i domini principali secondo l' elenco del suffisso pubblico ( publicsuffix.org ) di Mozilla fossero gestiti come un blocco. Potrei a un certo punto venire a farlo (sarebbe bello avere un progetto), qualcun altro interessato?
phk,

Risposte:


15

Questo semplice script Python farà quello che vuoi. In questo esempio il nome del file 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])

Per eseguirlo utilizzare:

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

Si noti che questo sembra un po 'più brutto da quando ho scritto questo come più o meno un semplice liner che ho dovuto usare la notazione di fetta di[::-1] dove funzionano i valori negativi per fare una copia dello stesso elenco in ordine inverso invece di usare il più dichiarativo reverse()che lo fa sul posto in un modo che rompe la componibilità.

Ed ecco una versione leggermente più lunga, ma forse più leggibile che utilizza reversed()che restituisce un iteratore, quindi la necessità di includerlo anche list()per consumare l'iteratore e produrre un elenco:

#!/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)))

Su un file con 1.500 righe ordinate casualmente ci vogliono ~ 0,02 secondi:

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

Su un file con 150.000 righe ordinate casualmente ci vogliono poco più di 3 secondi:

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

Ecco una versione discutibilmente più leggibile che fa reverse()e sort()sul posto, ma gira nello stesso lasso di tempo e occupa effettivamente un po 'più di memoria.

#!/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)

Su un file con 1.500 righe ordinate casualmente ci vogliono ~ 0,02 secondi:

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

Su un file con 150.000 righe ordinate casualmente ci vogliono poco più di 3 secondi:

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

Mi è piaciuto vedere molte soluzioni. Accetto la risposta basata su Python principalmente perché è quello che uso per molti dei miei altri script. Anche le altre risposte sembrano funzionare.
Zoredache,

1
Se qualcuno è interessato a ordinare prima per nome di dominio, ignorando TLD, usadata.sort(key=lambda x: x[1:])
Calimo

9

Ecco uno script di PowerShell che dovrebbe fare quello che vuoi. Fondamentalmente, getta tutti i TLD in un array che inverte ciascun TLD, lo ordina, lo riporta al suo ordine originale e quindi lo salva in un altro file.

$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

L'ho eseguito su 1.500 record - ha impiegato 5 secondi su un desktop ragionevolmente potente.


Dovrebbe essere abbastanza semplice convertire questo script in bash o in un'altra lingua, penso.
Mark Henderson

5 secondi sembrano molto tempo per solo 1.500 linee. La mia implementazione di Python fa 1.500 in una frazione di secondo e 150.000 in poco più di 3 secondi. Cosa pensi che lo renda così lento in PowerShell?
aculich,

Sì, è da tanto tempo. Non ho idea del perché ci vuole così tanto tempo. Probabilmente perché PowerShell non è davvero finalizzato a fare cose del genere.
Mark Henderson

7

cat domain.txt | rev | ordina | rev


Immagino che avrebbe funzionato. Mi piace che il TLD sia ordinato, e questo non lo farebbe. Usando questo, i TLD nel mio esempio sarebbero nell'ordine (uk, mil, pl, com, edu, gov) Dal momento che è un semplice ordinamento da destra a sinistra, anziché i confini del dominio.
Zoredache,

la migliore risposta che abbia mai visto!
Daniel,

1
rev domain.txt|sort|rev
Ricco

6

Leggermente meno criptico, o almeno più grazioso, Perl:

use warnings;
use strict;

my @lines = <>;
chomp @lines;

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

print "$_\n" for @lines;

Questo è un semplice esempio di trasformazione di Guttman-Rosler : convertiamo le linee nella forma ordinabile appropriata (qui, suddividiamo il nome di dominio in punti e invertiamo l'ordine delle parti), ordiniamo usando l'ordinamento lessicografico nativo e poi convertiamo il le linee tornano alla loro forma originale.


6

Negli script Unix: reverse, sort e reverse:

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}'

Cosa simile con un singolo loop: awk -F. '{for(i=NF;i>0;i--){printf ".%s",$i};printf "\t%s\n",$0}' file|sort|cut -f2potrebbe voler prima eliminare gli host locali congrep \. file | awk ...
Rich

3

Eccolo in (breve e criptico) 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" }

Hai informazioni sui tempi per questo tipo? Sono curioso di vedere come questo si confronta con l'implementazione PowerShell di @ Mark-Henderson , così come la mia implementazione Python . Ho usato /usr/bin/time -vper il tempo trascorso e le statistiche di memoria massima.
aculich,

4
Perl VINCE totalmente all'offuscamento.
Massimo,

4
Descrivere uno script Perl come "breve e criptico" è ridondante.
Belmin Fernandez,

@aculich, ad eccezione dello script PowerShell, tutte le opzioni sembrano richiedere meno di 0,1 secondi sul mio file.
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}'

Quello che fa è invertire ciascuno archiviato nel nome di dominio, ordinare e tornare indietro.

Questo ordina veramente l'elenco di domini, basato sul lessicografo su ciascuna parte del nome di dominio, da destra a sinistra.

La soluzione inversa ( rev <<<filename>>> | sort | rev), no, l'ho provata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.