为每个tld创建多个文件并对每个文件进行排序

时间:2011-12-23 23:18:05

标签: perl tld

我有一百万个网址。我必须为每个网址提取TLD,并为每个TLD制作多个文件。例如,使用.com收集所有网址作为tld并将其转储到1个文件中,另一个申请.edu tld等等。在每个文件中,我必须按字母顺序按域名对子域名进行排序。 CT 任何人都可以在perl中使用它来跳转吗?

我使用URI模块为每个网址提取tld,域名和主机名。 如何使用com tld收集所有Web地址并将其转储到1个文件中? 以及如何通过tld,然后按域,然后通过子域等对每个文件进行排序? 有什么指针吗?

while(my $line = <$fh1>){   

my $url = $line;

 my @components =  split(/\./, $url);
 my $n_comp = ($components[-1] =~ /^edu|com|net|org|gov$/) ? 2 : 3;
 my $domain = lc(join '.', @components[-$n_comp .. -1]);
 $domain =~ s/^\.//;  # Remove leading . if there is one.
 print $fh3 $domain;
        print $fh3 "\n";


  my $host = URI->new($url)->host();

 # Treat relative URLs as absolute URLs with missing http://.
 $url = "http://$url" if $url !~ /^\w+:/;



 $host =~ s/\.\z//;  # D::PS doesn't handle "domain.com.".
 print $fh2 $host;
 print $fh2 "\n";
 $dps->get_root_domain($host)
 or die $dps->error();
 print $fh4 $dps->tld();
 print $fh4 "\n";


 }

1 个答案:

答案 0 :(得分:0)

这应该适合你。

use strict;
use warnings;
use autodie;

open my $input, '<', shift @ARGV;
my %domain;
while( <$input> ){
  chomp;
  #                                   (  protocol   ) (  domain ) (rest)
  my ($protocol,$domain,$remain) = /^ (?:(\w+):\/\/)? ([^\\\/#]+) ( .* ) /x;

  my ($tld,@domain) = reverse split /[.]/, $domain;

  my $cmp = join '.', @domain;
  push @{ $domain{$tld} }, [ $cmp, $remain, $_ ];
}
close $input;

while( my($tld,$list) = each %domain ){
  open my $out, '>', $tld;
  print {$out} "$_\n" for map{
    $_->[-1]
  }sort{
    $a->[0] cmp $b->[0] ||
    $a->[1] cmp $b->[1] ||
    $a->[2] cmp $b->[2]
  } @$list;
  close $out;
}

  1. 首先,我们将输入分解为我们需要的部分。

    /^ (?:(\w+):\/\/)? ([^\\\/#]+) ( .* ) /x;
    
    • 这将匹配可选的http://或类似内容。

      (?:(\w+):\/\/)?
    • 这与\/#之外的任何内容都匹配,因为这些字符通常位于域之后。

      ([^\\\/#]+)
    • 这当然与剩下的任何东西相匹配。

      ( . )
  2. 我们希望对从顶级域到最低级别域的URL进行排序。所以我们split域名,reverse域名。

    my ($tld,@domain) = reverse split /[.]/, $domain;
    
  3. 要比较两个网址,我们需要一个易于比较的字符串。

    my $cmp = join '.', @domain;
    
  4. 存储信息以供日后使用。

    push @{ $domain{$tld} }, [ $cmp, $remain, $_ ];
    
  5. Open我们要打印的文件。

    while( my($tld,$list) = each %domain ){
      open my $out, '>', $tld;
    
  6. Sort进入当前文件的网址列表。

    ...
    sort{
      $a->[0] cmp $b->[0] ||
      $a->[1] cmp $b->[1] ||
      $a->[2] cmp $b->[2]
    } @$list;
    
  7. Map实际网址列表。

    ...
    map{
      $_->[-1]
    }
    ...
    
  8. Print将文件中的每个网址添加到文件中。

    print {$out} "$_\n" for ...