2010-12-13 9 views
1

ファイルの各行を読み込み、idフィールドを取得し、ユーティリティを実行して名前を取得し、最後に名前を追加する小さなスクリプトがあります。問題は、入力ファイルが膨大であること(2GB)です。出力は10-30文字の名前が付加された入力と同じなので、同じ桁の大きさです。どのようにして大きなバッファを読み込み、バッファで処理してバッファに書き込んでファイルへのアクセスを最小限に抑えるために最適化できますか?kshスクリプトの最適化

#!/bin/ksh 
while read line 
do 
    id=`echo ${line}|cut -d',' -f 3` 

    NAME=$(id2name ${id} | cut -d':' -f 4) 

    if [[ $? -ne 0 ]]; then 
     NAME="ERROR" 
     echo "Error getting name from id2name for id: ${id}" 
    fi 

    echo "${line},\"${NAME}\"" >> ${MYFILE} 
done < ${MYFILE}.csv 

おかげ

答えて

1

あなたは、ループの各反復でcutを2回呼び出しを排除することで、かなり物事をスピードアップすることができます。また、出力ファイルへのリダイレクションをループの最後まで移動する方が速いかもしれません。あなたは、入力ラインの例を示し、または何id2name(それがボトルネックだことは可能です)またはその出力がどのようなものか、私はこの近似を提供することができますから構成されていないので:

#!/bin/ksh 
while IFS=, read -r field1 field2 id remainder # use appropriate var names 
do 
    line=$field1,$field2,$id,$remainder 
    # warning - reused variables 
    IFS=: read -r field1 field2 field3 NAME remainder <<< $(id2name "$id") 
    if [[ $? -ne 0 ]]; then 
     NAME="ERROR" 
     # if you want this message to go to stderr instead of being included in the output file include the >&2 as I've done here 
     echo "Error getting name from id2name for id: ${id}" >&2 
    fi 
    echo "${line},\"${NAME}\"" 
done < "${MYFILE}.csv" > "${MYFILE}" 

OSが行いますあなたのためのバッファリング。

編集:

のkshのバージョンが<<<を持っていない場合は、これを試してみてください。

id2name "$id" | IFS=: read -r field1 field2 field3 NAME remainder 

(あなたがバッシュを使用していた場合、これは動作しません。)

+0

デニスに感謝します。 id2nameはidに基づいてユーザー名を取得し、ユーティリティを制御することはできません。しかし、私はIDと対応する名前を持って、dbを打つ前にローカル検索をしたい。タイプセット-Aを試しましたが、kshでは認識されません。 SunOSでは残念ながらksh93は利用できません。代替ソリューションはありますか?ありがとう – Kiran

+0

Hmm、行の構文エラーを取得しています。IFS =:read -r field1 field2 field3 NAME remainder <<< $(id2name $ id) 9行目の文法エラー: '<'予期しない <<<または私の解釈の悪いバージョンですか? – Kiran

+0

@キラン:私の編集された答えを見てください。 –