web-dev-qa-db-ja.com

スクリプト(bash、awkなど)を使用してファイル内の他のドメインのサブドメインを整理する

私はドメインから成る巨大なサイズのファイル(1万エントリ)を持っています(ランダムな順序ですが、重複ドメインはなく、任意の数のサブドメインがあります)、ここに小さな例があります:

domain.com
domain.net
sub.domain.com
anotherdomain.com
a.b.c.d.e.domain.net
5.4.3.2.1.domain.org
4.3.2.1.domain.org

編集:適切なワーキングセットは http://p.ip.fi/WRD- で入手できます(Webページは低速で、wget p.ip.fi/WRD-を使用してすぐにダウンロードできます)。

すべてのサブドメインを「削除」します。つまり、他のドメインのすべてのサブドメインを削除する新しいファイルを作成します。その例では、次のようになります(ソートは気にしないでください)。

domain.com
domain.net
anotherdomain.com
4.3.2.1.domain.org

sub.domain.coma.b.c.d.e.domain.netおよび5.4.3.2.1.domain.orgは削除され(domain.comdomain.netおよび4.3.2.1.domain.orgのサブドメインであるため)、anotherdomain.comが保持されます、それはちょうど別のドメインだからです。

いくつかの最適化でさまざまなアプローチを試しましたが、うまくいきましたが、ファイルに1万のエントリがあるため、速度が遅すぎます(何時間も)。役立つためには、高速でなければなりません(最大1分程度)。これが私が今持っているものです:

> $TEMP_BLACKLIST
BL=`cat $BLACKLIST`
for ZONE1 in $BL; do
        KEEP=1
        # sed -e "1,/^$ZONE1$/d" -> optimization: print $BLACKLIST only *after* the $ZONE1 occourence
        # break                  -> optimization: quit the loop if not present
        for ZONE2 in `echo $BL | sed -e "1,/^$ZONE1$/d"`; do
                if [[ $ZONE1 == *.$ZONE2 ]] ; then
                        KEEP=0
                        break
                fi
        done
        if [ $KEEP = 1 ] ; then
                echo $ZONE1 >> $TEMP_BLACKLIST
        fi
done
mv $TEMP_BLACKLIST $BLACKLIST

コードはbashスクリプト内に含める必要があるため、bashだけで、最終的にはそこから呼び出される一般的な埋め込みスクリプト言語(awk、Perlなど)を呼び出します(カスタムCコードなし)。

より良いアプローチを知っていますか?

5
Fabio

これは別のバージョンです

sed 's/^/\./' file |
    rev |
    LC_ALL=C sort -u |
    awk 'p == "" || substr($0,1,length(p)) != p { print $0; p = $0 }' |
    rev |
    sed 's/^\.//'

入力

domain.com
domain.net
sub.domain.com
anotherdomain.com
a.b.c.d.e.domain.net
5.4.3.2.1.domain.org
4.3.2.1.domain.org
b.c
a-b.c
b.b.c
btcapp.api.btc.com
btc.com

出力

a-b.c
b.c
4.3.2.1.domain.org
btc.com
domain.com
anotherdomain.com
domain.net

http://p.ip.fi/WRD- の推奨データセットを試すと、収集したソースファイルには59683行が含まれ、フィルターされたリストには34824行あります。36行にgrep btc.com | wc -lフィルター済みリストに適用されます。

3
roaima

これを試して、

rev file \
| sort -u \
| tr '.' ',' \
| awk '$0!~dom_regex{print;dom_regex="^"$0"[.]";};NR==1{dom_regex="^"$0"[.]";print};' \
| tr ',' '.' \
| rev

出力:

4.3.2.1.domain.org
domain.com
anotherdomain.com
domain.net

説明:

  1. sort逆転されたファイルと重複行を排除します。このステップでは、「1種類」のドメイン/サブドメインを、最短のものと一緒にグループ化します。
  2. awk部分は、次のものが同じ種類であるかどうかを調べます(変数dom_regexに正規表現として保存されています)。そうでない場合は、行を出力して新しいdom_regexを設定します。それ以外の場合、行はスキップされます。
  3. もう一度ファイルを元に戻します。
4
pLumo

ドメイン拡張が1つしかない場合は、これを試してください。

awk -F '.' '!seen[$(NF-1)"."$NF]++' file

domain.com
domain.net
anotherdomain.com
2
msp9011