排序从tld开始到左侧的域名(FQDN)列表


20

我正在寻找从TLD开始向上的域名列表(网络过滤器白名单)。我正在寻找可以轻松实现此目的的任何* nix或Windows工具,尽管脚本也可以。

因此,如果给出的是列表

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

这就是我想要的输出。

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

以防万一您想知道Squidguard为什么会有bug /设计缺陷。如果两个www.example.comexample.com都包含在一个列表中,然后example.com进入被忽略,你只能访问与内容www.example.com。我有几个大列表需要清理,因为有人添加了条目而没有先看。


com域不应该出现edu在排序列表中吗?
斯文

9
是的,我无法进行手动排序,这就是为什么我要寻找工具的原因。:)
Zoredache


3
另外,与perl版本相比,那里的python版本还不错,因为python的排序适用于列表列表。perl的排序不是必须执行。
马克·瓦格纳

1
顺便说一句,如果OP根据Mozilla的公共后缀(publicsuffix.org)清单要求将顶级域名作为一个整体来处理,这将更具挑战性。我可能会在某个时候开始做它(这对一个项目来说是个不错的选择),还有其他人感兴趣吗?
phk

Answers:


15

这个简单的python脚本将满足您的需求。在此示例中,我将文件命名为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])

要运行它,请使用:

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

请注意,这看起来有点丑陋,因为我写这更多或更少的一个简单的一行,我不得不使用的切片表示法[::-1],其中负值工作,使以相反的顺序相同列表的副本,而不是使用更声明reverse()这是否以破坏可组合性的方式就地执行它。

这是一个稍长但可能更具可读性的版本,reversed()该版本使用它返回迭代器,因此需要将其包装起来list()以使用迭代器并生成列表:

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

对于具有1500条随机排序的行的文件,大约需要0.02秒:

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

对于具有150,000条随机排序的行的文件,需要3秒钟多一点的时间:

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

这可以说是更易读的版本,它执行reverse()sort()就地操作,但运行时间相同,实际上占用了更多的内存。

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

对于具有1500条随机排序的行的文件,大约需要0.02秒:

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

对于具有150,000条随机排序的行的文件,需要3秒钟多一点的时间:

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

我喜欢看到很多解决方案。我接受基于python的答案主要是因为这是我在许多其他脚本中使用的答案。其他答案似乎也都起作用。
Zoredache

1
如果有人有兴趣先忽略域名(TLD)来按域名排序,请使用data.sort(key=lambda x: x[1:])
Calimo

9

这是应该执行所需操作的PowerShell脚本。基本上,它会将所有TLD放入一个数组中,以对每个TLD进行反转,排序,将其反转回到其原始顺序,然后将其保存到另一个文件中。

$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

在1,500条记录上运行-在功能强大的台式机上花了5秒钟。


将这个脚本转换为bash或我认为的另一种语言应该相当简单。
马克·亨德森

5秒似乎只需要1500条线就很长了。我的python实现在不到一秒的时间内完成了1,500,而在3秒钟内完成了150,000。您认为是什么使它在PowerShell中如此缓慢?
aculich 2012年

是的,很长一段时间。我不知道为什么要花这么长时间。可能是因为powershell并非真正针对这样的事情。
马克·亨德森

7

猫domain.txt | 转速| 排序| 转速


我想那行得通。我确实希望对TLD进行排序,但这无法实现这一点。使用此方法,在我的示例中,TLD的顺序应为(uk,mil,pl,com,edu,gov),因为这是一种简单的从右到左排序,而不是域边界。
Zoredache

我见过的最好的答案!
丹尼尔(Daniel)

1
rev domain.txt|sort|rev
Rich

6

Perl的神秘性稍差,或者至少更漂亮:

use warnings;
use strict;

my @lines = <>;
chomp @lines;

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

print "$_\n" for @lines;

这是Guttman-Rosler变换的一个简单示例:我们将这些行转换为适当的可排序形式(此处,按句点分割域名并颠倒各部分的顺序),使用本机词典顺序对它们进行排序,然后将线恢复到其原始形式。


6

在Unix脚本中:反向,排序和反向:

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

一个循环就awk -F. '{for(i=NF;i>0;i--){printf ".%s",$i};printf "\t%s\n",$0}' file|sort|cut -f2可以grep \. file | awk ...
Rich

3

这是在(简短而神秘的)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-Henderson的PowerShell实现以及我的Python实现相比如何。我使用/usr/bin/time -v了经过时间和最大内存统计信息。
aculich 2012年

4
Perl在混淆时完全胜出。
马西莫

4
将Perl脚本描述为“简短而神秘”是多余的。
Belmin Fernandez

@aculich,除了powershell脚本外,所有选项似乎对我的文件只花了不到0.1秒的时间。
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}'

这样做是将域名中的每个文件都反向,排序并反向反向。

这样就可以根据域名的各个部分从右到左按字典顺序对域名列表进行真正的排序。

反向解决方案(rev <<<filename>>> | sort | rev)不会,我已经尝试过了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.