оптимизация ksh-скрипта - PullRequest
       1

оптимизация ksh-скрипта

1 голос
/ 13 декабря 2010

У меня есть небольшой скрипт, который просто читает каждую строку файла, извлекает поле id, запускает утилиту для получения имени и добавляет имя в конце.Проблема в том, что входной файл огромен (2 ГБ).Поскольку выходные данные совпадают с входными данными с добавленным именем из 10-30 символов, они имеют тот же порядок величины.Как я могу оптимизировать его для чтения больших буферов, обработки в буферах и последующей записи буферов в файл, чтобы минимизировать количество обращений к файлу?

#!/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 Ответ

1 голос
/ 13 декабря 2010

Вы можете значительно ускорить процесс, исключив два вызова 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, это не сработало бы.)

...