是否有更好的方法將域和子域排序和分組在一起?例如,list
包含的文件
morefu.sub1.foo.com
www.foo.com
bar.foo.com
sub1.foo.com
fufu.isub1.foo.com
foofoo.bar.foo.com
morefoo.bar.foo.com
fufu.sub1.foo.com
使用
for i in $(grep -oP '(\w+).foo.com' list | sort | uniq); do grep $i list | sort; echo; done
幾乎有效:
bar.foo.com
foofoo.bar.foo.com
lotsmorefubar.bar.foo.com
morefoo.bar.foo.com
fufu.isub1.foo.com <-- should not be here
fufu.sub1.foo.com
morefu.sub1.foo.com
sub1.foo.com
www.foo.com
但fufu.isub1.foo.com
它應該單獨在一個部分中。在 grep 表達式中加入^
and\b
沒有幫助。
想知道是否有更準確、更有效的方法來做到這一點?
答案1
怎麼樣
tr -d [:blank:] < hosts | # remove trailing whitespace
perl -lne 'print join ".", reverse(split /\./)' | # reverse order of fields
sort | # sort
awk -F. '
!seen[$1.$2.$3]++ && NR>1 {print ""} # insert blank line when tld,dom,sub change
{for (i=NF;i>1;i--) printf "%s.", $i; print $1} # print fields in original order
'
給予
bar.foo.com
foofoo.bar.foo.com
morefoo.bar.foo.com
fufu.isub1.foo.com
sub1.foo.com
fufu.sub1.foo.com
morefu.sub1.foo.com
www.foo.com
使用相同的演算法更好(我希望)實現哈希值的哈希值在 Perl 中:
#!/usr/bin/perl
use strict;
use warnings;
my %domains = ();
while (defined($_ = <ARGV>)) {
chomp $_ ;
$_ =~ s/\s+//;
my @F = reverse(split(/\./));
my $domain = join(".", @F[0..2]);
if ( ! exists($domains{$domain}) ) {
$domains{$domain} = {};
}
$domains{$domain}{join(".", @F)}++;
}
foreach my $domain (sort keys %domains) {
foreach my $host (sort keys %{ $domains{$domain} }) {
print join(".", reverse(split(/\./, $host))), "\n";
}
print "\n"
}
答案2
TXR口齒不清:
[(opip (mapcar (op tok-str @1 #/[^.]+/))
(sort @1 : reverse)
(partition-by (ret [@1 -3..-1]))
(mapcar (op mapcar (op cat-str @1 ".")))
(interpose "")
tprint)
(get-lines)]
跑步:
$ txr domain-sort.tl < data
bar.foo.com
foofoo.bar.foo.com
morefoo.bar.foo.com
fufu.isub1.foo.com
sub1.foo.com
fufu.sub1.foo.com
morefu.sub1.foo.com
www.foo.com
基本上,我們將行標記為字串列表,例如("sub1" "foo" "com")
, 並使用這些列表。我們使用其元素的逆序作為鍵對該列表進行排序;因此,為了排序的目的,("sub1" "foo" "com")
被視為("com" "sub1" "foo")
。之後,就是分組的問題了。使用partition-by
,使用最後三個元素作為分區鍵可以輕鬆實現這一點。我們必須透過用句點連接字串來重新建構字串,並用行列印群組。後者是透過在群組之間插入空字串並讓其tprint
完成其工作來實現的。