スクリプト(bash、awkなど)を使用して、ファイル内の他のドメインのサブドメインをクリーンアップします。

スクリプト(bash、awkなど)を使用して、ファイル内の他のドメインのサブドメインをクリーンアップします。

ドメイン(ランダムな順序ですが、冗長ドメインがなく、サブドメインの数が制限されていない)を含む大容量ファイル(10,000エントリ)があります。以下は小さな例です。

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-(ウェブページが遅いです。wget p.ip.fi/WRD-instant downloadを使用してください。)

すべてのサブドメインを「クリーンアップ」したいです。つまり、他のドメインのすべてのサブドメインを削除する新しいファイルを作成したいと思います。例では、次のようにしてください(注文には気を付けないでください)。

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.com、、およびdomain.netのサブドメインとして4.3.2.1.domain.org)削除され、anotherdomain.com他のドメインであるため、そのまま残ります。

さまざまな方法といくつかの最適化を試みましたが、うまくいきますが、ファイルに10,000項目があるため、遅すぎます(数時間)。便利に使用するには、速度が速くなければなりません(最大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コードなし)。

より良い方法を知っていますか?

答え1

この試み、

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. ファイルをもう一度反転してみてください。

答え2

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

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行があります。grep btc.com | wc -lフィルタリングされたリストに36行が適用されていることがわかります。

答え3

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

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

domain.com
domain.net
anotherdomain.com

関連情報