grep検索に基づいてスクリプトを高速化する方法は?

grep検索に基づいてスクリプトを高速化する方法は?

2つのカンマ区切り値を含む非常に大きなテキストファイルがあります。

78414387,10033
78769989,12668
78771319,13677
78771340,13759
80367563,16336
81634533,10025
82878571,10196
110059366,10218
110059411,10812
110059451,10067

次のようにログファイルからその値を取得する必要があります。

- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c737e3d80d7def296c7| id=278832702| version=28| timestamp=1467432051000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c732f18c26fe604fd04| id=284057302| version=9| timestamp=1467432051000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c747e3d80d7def296c8| id=357229| version=1151| timestamp=1467432052000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c742f18c26fe604fd05| id=279832706| version=35| timestamp=1467432052000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c744697ddb976cf5a95| id=354171| version=503| timestamp=1467432052000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:53 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c754697ddb976cf5a96| id=355638| version=1287| timestamp=1467432053000

私のスクリプト:

#!/bin/bash
COUNT=0
while IFS=',' read ID VERSION; do
    VERSION=`echo $VERSION |col -bx`
    if (grep "id=${ID}| version=$VERSION" worker-6715.log.2016-$1.log.* > /dev/null); then
            let "COUNT++"
    else
            echo "$ID, $VERSION FAIL"
            exit 2

    fi
done < recon.txt

echo "All OK, $COUNT checked"
  • ログファイルから不要なフィールドを削除すると実行速度が速くなりますか?
  • RAMデバイスを作成してそこにログファイルをコピーすると、実行速度が速くなりますか?Red Hat Linux 6(Hedwig) ファイルをキャッシュする方法は?他に提案がありますか?

ベストアンサー1

ボトルネックは、recon.txtシェルからファイルを1行ずつ読み取っています。失敗した行を取得するには、ログ内の行を前処理して行のように見えるようにし、それを使用してrecon.txtcomm(1)のように設定の違いを見つけることができます。

comm -23 \
    <(sort -u recon.txt) \
    <(sed 's/.*| id=\([0-9]*\)| version=\([0-9]*\)|.*/\1,\2/' worker-6715.log.2016-$1.log.* | \
        sort -u)

これは、構成を処理できるシェルがあると仮定します<(...)。また、結果の行の順序は維持されませんrecon.txt。この順序を維持することはより困難で遅いでしょう。

成功回数も必要な場合は、反対の操作を実行してrecon.txtログで見つかったのと同様に見えるように前処理してから、またはをfgrep(1)使用grep -Fして検索できます。ロケールを次に設定すると、C一部のシステムで作業速度が大幅に向上する可能性があります。したがって:

COUNT=$( \
    sed 's/\([0-9]*\),\([0-9]*\)/| id=\1| version=\2|/' recon.txt | \
    LC_ALL=C fgrep -f - worker-6715.log.2016-$1.log.* | \
    wc -l )

これはrecon.txt、重複エントリを含まず、各行がすべてのrecon.txtログで最大1回一致することを前提としています。最初の制限を解除するのは難しいでしょう。 2番目は慎重な選択で持ち上げることができますcomm(1)

おすすめ記事