2010-12-13 165 views
1

我有一個小腳本,只讀取文件的每一行,檢索id字段,運行實用程序獲取名稱並在末尾附加名稱。問題是輸入文件很大(2GB)。由於輸出與添加了10-30個char名稱的輸入相同,因此它具有相同的數量級。我怎樣才能優化它來讀取大型緩衝區,在緩衝區中進行處理,然後將緩衝區寫入文件,從而使文件訪問次數最小化?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大大加快速度。將重定向移動到輸出文件到循環結束可能會更快。既然你不顯示輸入行的例子,或者什麼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}" 

操作系統會做爲你緩衝。

編輯:

如果你的KSH的版本沒有<<<,試試這個:

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

(如果你使用bash,這是行不通的)

+0

謝謝丹尼斯。 id2name根據id獲取用戶名,我無法控制該實用程序。但是,我希望擁有ID和相應的名稱,並在擊中數據庫之前執行本地查找。我嘗試排版-A,但它不被ksh識別。不幸的是,在SunOS上,ksh93不可用。有其他解決方案嗎?謝謝 – Kiran 2010-12-13 19:54:05

+0

嗯,得到這條線的語法錯誤:IFS =:讀-r field1 field2 field3 NAME其餘<<< $(id2name $ id) 語法錯誤在第9行:'<'意外 它是<<而不是<<<或者是我的解釋器不好的版本? – Kiran 2010-12-13 20:01:12

+0

@Kiran:看到我編輯的答案。 – 2010-12-13 21:11:25