도메인과 하위 도메인을 함께 정렬하고 그룹화하는 더 좋은 방법이 있습니까? 예를 들어, 다음을 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 표현식에 ^
및를 추가해도 도움이 되지 않았습니다.\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
(나는 희망한다) 동일한 알고리즘을 더 잘 구현한다.해시의 해시펄에서:
#!/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
해당 작업을 수행함으로써 달성됩니다.