1

ファイル「tmpcsv2」の一連の変数を「uniq_id」の変数と比較する必要があります。以下にファイルの詳細を示します。

tmpcsv2 -> このファイルは別のスクリプト 'script1' によって更新され、'script1' の実行ごとに 'tmpcsv2' の新しい変数が更新されます (追加ではありません)。いいえ。変数の数は 1 から 200 まで可能です。

eg:
2042344352
2470697747
2635527510
3667769962

uniq-id -> これは変数の固定セットです (数で約 100K)。

(Business Name,Job ID,Job Size)
biz,1000036446,225210640
biz,100006309,6710840
biz,1000069211,2084019000
biz,1000118720,34194040
biz,1000150241,212322636

以下に示すように、「for」ループと「if」を使用してそれらを比較していますが、これを行うためのより簡単または高速な (影響の少ない) 方法はありますか? これを実行すると、結果を出力するのに非常に長い時間がかかります。印刷コマンドはテスト用であり、後で削除されます!

****Part of a bigger script****
amt=0
mjc=0
for jbid in `cat tmpcsv2` #Pick ID for match & calculation
do
    printf "Checking ID $jbid\n" >> Acsv3.tmp
    for bsid in `cat uniq_id` #Matching jobs & size calulation
    do
        ckid=`echo $bsid | cut -d "," -f2` #ckid is the ID to check
        jbsiz=`echo $bsid | cut -d "," -f3` #size of the ID
        if [ $jbid == $ckid ] 
        then
            printf "Matched at $ckid\n" #Print on Match found
            printf "Valid -> $jbid\n" >> Bcsv3.tmp
            ((mjc++)) #Increment Matched Job Count
            amt=$((amt+jbsiz)) #Add size of matched jobs
            break
        else
            printf "No Match at $cksid\n" #No matches
        fi
    done
    printf "Check for ID $jbid done\n" >> Acsv3.tmp
    printf "Matched $mjc jobs with combined size of $amt\n" >> Acsv3.tmp
done
****End of Comparision****
4

2 に答える 2

1

シェルは、これほど多くのデータを処理するための不適切なツールですが、実行可能です。ここでの最も基本的な間違いは、 で行を読むことforです。各反復でファイルを再度開かないことで、パフォーマンスが大幅に向上する場合があります。

function main {
    # Variables used elsewhere should be initialized there, not localized here.
    typeset amt=0 mjc=0 jbid ckid jbsiz

    while IFS= read -r jbid; do
        printf 'Checking ID %s\n' "$jbid" >&3
        while IFS=, read -r _ ckid jbsiz _; do
            case $jbsiz in
                *[^[:digit:]]*|'')
                    # validation is important for subsequent arithmetic.
                    return 1
                    ;;
                "$ckid") # Assuming "cksid" was a typo. Replace if not.
                    printf 'Matched at %s\n' "$ckid"
                    printf 'Valid -> %s\n' "$jbid" >&4
                    (( mjc++, amt += jbsiz ))
                    break
                    ;;
                *)
                    printf 'No match at %s\n' "$ckid"
            esac
        done <uniqid
        {
            printf 'Check for ID %s done\n' "$jbid"
            printf 'Matched %s jobs with combined size of %s\n' "$mjc" "$amt"
        } >&3
    done <tmpcsv2 3>>Acsv3.tmp 4>>Bcsv3.tmp
}

最後に、同等の awk スクリプトは、他のほとんどの言語と同様に、この Bash スクリプトよりも大幅に優れています。読み取りループの代わりに使用することで、Bash のパフォーマンスを大幅に向上させることもできますmapfileが、このネストされた読み取りループ ロジックは、mapfileコールバックを使用してエミュレートするのが少し雑です。

于 2013-03-22T12:46:38.517 に答える
0

これを思いついたのですが、これを短縮できるかどうかはわかりませんが、確実に高速に実行されます! どんな助けでも大歓迎です!

************
while read -r line  #File read start
do
IFS=$","
val=$line
amt=0
mjc=0
cjc=0
for lsid in $val
do
    cksid=`echo $lsid | sed -e 's/*//g' -e 's/"//g'`
    printf "Checking for $cksid\n"
    ((cjc++)) #Count of jobs to check
    prsnt=`grep -w $cksid uniq_id`
    if [ $? -eq 0 ]
    then
        printf "Valid -> $cksid\n"
        jbsiz=`grep -w $prsnt | cut -d, -f2`
        (( mjc++, amt += jbsiz ))
        break
    else
        printf "No Data for $cksid\n"
    fi

done
done < tmpcsv2
***********
于 2013-03-24T06:49:49.907 に答える