Gibt es eine bessere Möglichkeit, Domänen und Subdomänen zu sortieren und zu gruppieren? Beispielsweise die Datei list
mit
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
mit
for i in $(grep -oP '(\w+).foo.com' list | sort | uniq); do grep $i list | sort; echo; done
funktioniert fast:
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
mit der Ausnahme, fufu.isub1.foo.com
dass es in einem eigenen Abschnitt stehen sollte. Das Hinzufügen von ^
und \b
zum Grep-Ausdruck hat nicht geholfen.
Sie fragen sich, ob es hierfür einen genaueren und effizienteren Weg gibt?
Antwort1
Wie wäre es mit
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
'
Geben
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
Bessere (hoffentlich) Implementierung des gleichen Algorithmus unter Verwendung einesHash von Hashesin 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"
}
Antwort2
TXRLispeln:
[(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)]
Laufen:
$ 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
Im Grunde tokenisieren wir die Zeilen in Listen von Zeichenfolgen wie ("sub1" "foo" "com")
und arbeiten mit einer Liste dieser. Wir sortieren diese Liste mit der Umkehrung ihrer Elemente als Schlüssel; zum Zwecke der Sortierung ("sub1" "foo" "com")
wird also so behandelt, als wäre es ("com" "sub1" "foo")
. Danach geht es um die Gruppierung. Dies lässt sich leicht mit erreichen partition-by
, wobei die letzten drei Elemente als Partitionierungsschlüssel verwendet werden. Wir müssen die Zeichenfolgen neu zusammensetzen, indem wir sie mit einem Punkt verbinden, und die Gruppen mit Zeilen drucken. Letzteres erreichen wir, indem wir eine leere Zeichenfolge zwischen den Gruppen einfügen und es tprint
seine Arbeit machen lassen.