Mengurutkan daftar nama domain (FQDN) mulai dari tld dan bekerja dengan kiri

20

Saya mencari untuk mengurutkan daftar nama domain (daftar putih filter web) mulai dari TLD dan bekerja ke atas. Saya mencari * nix atau alat windows yang dapat melakukan ini dengan mudah, meskipun skrip juga akan baik-baik saja.

Jadi jika daftar yang Anda berikan

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

Inilah yang saya inginkan sebagai 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

Kalau-kalau Anda bertanya-tanya mengapa, Squidguard, memiliki cacat bug / desain. Jika keduanya www.example.comdan example.comkeduanya termasuk dalam daftar, maka example.comentri tersebut diabaikan dan Anda hanya dapat mengunjungi konten dari www.example.com. Saya memiliki beberapa daftar besar yang perlu dibersihkan karena seseorang menambahkan entri tanpa melihat terlebih dahulu.

Sakit kepala
sumber
Bukankah seharusnya comdomain muncul sebelumnya edudalam daftar Anda yang diurutkan?
Sven
9
Yup, saya gagal dalam penyortiran manual, itulah sebabnya saya mencari alat. :)
Zoredache
3
Juga, versi python ada yang bagus dibandingkan dengan versi perl karena jenis ular sanca bekerja pada daftar daftar; perl perl tidak dan harus diimplementasikan.
Mark Wagner
1
Di samping catatan ini akan jauh lebih menantang jika OP telah meminta domain-top menurut daftar akhiran publik Mozilla ( publicsuffix.org ) untuk ditangani sebagai satu blok. Saya mungkin pada suatu saat datang untuk melakukannya (itu akan menjadi baik untuk memiliki proyek), siapa lagi yang tertarik?
phk

Jawaban:

15

Skrip python sederhana ini akan melakukan apa yang Anda inginkan. Dalam contoh ini saya memberi nama 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])

Untuk menjalankannya gunakan:

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

Perhatikan bahwa ini terlihat sedikit lebih buruk karena saya menulis ini lebih atau kurang satu-liner sederhana saya harus menggunakan notasi irisan di[::-1] mana nilai-nilai negatif bekerja untuk membuat salinan dari daftar yang sama dalam urutan terbalik daripada menggunakan lebih deklaratif reverse()yang melakukannya di tempat dengan cara yang merusak kompabilitas.

Dan ini versi yang sedikit lebih panjang, tapi mungkin lebih mudah dibaca yang menggunakan reversed()yang mengembalikan iterator, maka perlu juga membungkusnya list()untuk mengkonsumsi iterator dan menghasilkan daftar:

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

Pada file dengan 1.500 garis yang diurutkan secara acak, dibutuhkan ~ 0,02 detik:

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

Pada file dengan 150.000 garis yang disortir secara acak, dibutuhkan sedikit lebih dari 3 detik:

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

Ini adalah versi yang bisa dibilang lebih mudah dibaca yang melakukan reverse()dan sort()di tempat, tetapi berjalan dalam jumlah waktu yang sama, dan sebenarnya membutuhkan sedikit lebih banyak memori.

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

Pada file dengan 1.500 garis yang diurutkan secara acak, dibutuhkan ~ 0,02 detik:

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

Pada file dengan 150.000 garis yang disortir secara acak, dibutuhkan sedikit lebih dari 3 detik:

Elapsed (wall clock) time (h:mm:ss or m:ss): 0:03.08
Maximum resident set size (kbytes): 219152
aculich
sumber
Saya suka melihat banyak solusi. Saya menerima jawaban berdasarkan python sebagian besar karena itulah yang saya gunakan untuk banyak skrip saya yang lain. Jawaban lain semua tampaknya juga berfungsi.
Zoredache
1
Jika ada yang tertarik mengurutkan berdasarkan nama domain terlebih dahulu, mengabaikan TLD, gunakandata.sort(key=lambda x: x[1:])
Calimo
9

Berikut ini skrip PowerShell yang harus melakukan apa yang Anda inginkan. Pada dasarnya itu melemparkan semua TLD ke dalam array membalikkan setiap TLD, mengurutkannya, membalikkannya kembali ke urutan aslinya, dan kemudian menyimpannya ke file lain.

$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

Jalankan dengan 1.500 catatan - butuh 5 detik pada desktop yang cukup kuat.

Mark Henderson
sumber
Seharusnya cukup sederhana untuk mengubah skrip ini menjadi bash atau bahasa lain yang saya pikir.
Mark Henderson
5 detik sepertinya lama sekali hanya 1.500 baris. Implementasi python saya menghasilkan 1.500 dalam sepersekian detik, dan 150.000 hanya dalam waktu 3 detik. Menurut Anda apa yang membuatnya sangat lambat di PowerShell?
aculich
Ya itu waktu yang lama. Saya tidak tahu mengapa itu membutuhkan waktu begitu lama. Mungkin karena PowerShell tidak benar-benar bertujuan melakukan hal-hal seperti ini.
Mark Henderson
7

cat domain.txt | rev | sortir | putaran

pengguna3721740
sumber
Saya kira itu akan berhasil. Saya suka memiliki TLD disortir, dan ini tidak akan mencapai itu. Dengan menggunakan ini, TLD dalam contoh saya akan berada dalam urutan (uk, mil, pl, com, edu, gov) Karena ini adalah hak sederhana untuk menyortir kiri, bukan batas domain.
Zoredache
jawaban terbaik yang pernah saya lihat!
Daniel
1
rev domain.txt|sort|rev
Kaya
6

Sedikit kurang samar, atau setidaknya lebih cantik, Perl:

use warnings;
use strict;

my @lines = <>;
chomp @lines;

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

print "$_\n" for @lines;

Ini adalah contoh sederhana dari transformasi Guttman-Rosler : kami mengubah garis menjadi bentuk yang dapat diurutkan yang sesuai (di sini, pisahkan nama domain pada periode dan membalik urutan bagian-bagian), mengurutkannya menggunakan jenis leksikografi asli dan kemudian mengonversi garis kembali ke bentuk aslinya.

Ilmari Karonen
sumber
6

Di skrip Unix: membalikkan, mengurutkan dan membalikkan:

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
sumber
Hal serupa dengan satu loop: awk -F. '{for(i=NF;i>0;i--){printf ".%s",$i};printf "\t%s\n",$0}' file|sort|cut -f2Mungkin ingin menghapus host lokal terlebih dahulu dengangrep \. file | awk ...
Rich
3

Ini dia dalam perl (pendek dan samar):

#!/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
sumber
Apakah Anda memiliki informasi pengaturan waktu untuk jenis ini? Saya ingin tahu bagaimana perbandingannya dengan implementasi PowerShell @ Mark-Henderson , serta implementasi Python saya . Saya menggunakan /usr/bin/time -vuntuk waktu berlalu dan statistik memori maks.
aculich
4
Perl benar-benar MENANG di kebingungan.
Massimo
4
Menggambarkan skrip Perl sebagai "pendek dan samar" adalah berlebihan.
Belmin Fernandez
@aculich, dengan pengecualian skrip PowerShell, semua opsi tampaknya memakan waktu kurang dari 0,1 detik pada file saya.
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}'

Apa yang dilakukan adalah membalik setiap diajukan dalam nama domain, mengurutkan dan membalikkan kembali.

Ini benar-benar mengurutkan daftar domain, berdasarkan leksikografis pada setiap bagian nama domain, dari kanan ke kiri.

Solusi terbalik ( rev <<<filename>>> | sort | rev), tidak, saya sudah mencobanya.

Mike Rudra
sumber