2010-12-13 5 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에 두 통화를 제거하여 상당히 일을 속도를 높일 수 있습니다. 또한 출력 파일로의 리다이렉션을 루프의 끝으로 이동하는 것이 더 빠를 수도 있습니다.

#!/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가 할 것입니다 : 당신이 입력 라인의 예를 표시하지 않습니다, 또는 무엇 id2name가 구성되어 있기 때문에 또는 출력이 어떻게 생겼는지, 난 단지이 근사치를 제공 할 수 있습니다 (그것은 병목 현상의 가능) 너를위한 완충.

편집 : KSH 버전이 <<<이없는 경우

,이 시도 :

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

(. 당신이 배쉬를 사용한 경우, 문제가 해결되지 것)

+0

데니스에게 감사드립니다. id2name은 id를 기반으로 한 사용자 이름을 얻고 유틸리티에 대한 제어권이 없습니다. 그러나, 나는 ID와 해당 이름을 가지고 있고 DB를 치기 전에 로컬 조회를하고 싶습니다. 나는 typeset -A를 시도했지만 ksh에서는 인식되지 않는다. 불행히도 SunOS에서는 ksh93을 사용할 수 없습니다. 다른 해결책이 있습니까? 감사합니다 – Kiran

+0

흠, 줄 구문 오류가 발생 : IFS = : 읽기 -r field1 field2 field3 NAME 나머지 <<< $ (id2name $ id) 구문 오류가있는 줄 9 :'< '예기치 않은 << 대신 <<< 또는 내 해석자 나쁜 버전입니까? – Kiran

+0

@Kiran : 편집 된 답변보기. –