2010-12-13 3 views
1

У меня есть небольшой скрипт, который просто читает каждую строку файла, извлекает поле id, запускает утилиту для получения имени и добавляет имя в конце. Проблема заключается в том, что входной файл огромен (2 ГБ). Поскольку вывод такой же, как и вход с добавлением 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 в каждой итерации цикла. Возможно, быстрее переместить перенаправление в выходной файл в конец цикла. Так как вы не показывают пример строки ввода, или что 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}" 

ОС будет делать буферизация для вас.

Edit:

Если ваша версия KSH не <<<, попробуйте следующее:

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

(. Если вы используете Bash, это не будет работать)

+0

Спасибо Деннису. id2name получает имя пользователя на основе идентификатора, и я не имею никакого контроля над утилитой. Тем не менее, я хочу иметь идентификаторы и соответствующие имена и делать локальный поиск перед ударом db. Я попробовал typeset -A, однако он не распознается под ksh. К сожалению, на SunOS, ksh93 недоступен. Есть ли альтернативное решение? Спасибо – Kiran

+0

Хмм, получив синтаксическую ошибку для строки: IFS =: read -r field1 field2 field3 NAME осталось <<< $ (id2name $ id) ошибка синтаксиса в строке 9: '<'неожиданный Является ли это << вместо <<< или мой интерпретатор плохой версии? – Kiran

+0

@ Киран: См. Мой отредактированный ответ. –

Смежные вопросы