【问题标题】:ksh script optimizationksh脚本优化
【发布时间】:2010-12-13 17:56:11
【问题描述】:

我有一个小脚本,它简单地读取文件的每一行,检索 id 字段,运行实用程序来获取名称并在末尾附加名称。问题是输入文件很大(2GB)。由于输出与附加了 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

谢谢

【问题讨论】:

    标签: optimization file-io ksh


    【解决方案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 版本没有&lt;&lt;&lt;,试试这个:

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

    (如果您使用的是 Bash,这将不起作用。)

    【讨论】:

    • 谢谢丹尼斯。 id2name 根据 id 获取用户名,我无法控制该实用程序。但是,我想拥有 id 和相应的名称,并在访问数据库之前进行本地查找。我尝试了 typeset -A ,但是在 ksh 下无法识别。不幸的是,在 SunOS 上,ksh93 不可用。有没有替代的解决方案?谢谢
    • 嗯,出现以下行的语法错误:IFS=: read -r field1 field2 field3 NAME remaining
    • 谢谢,这行得通。此外,由于删除了剪切并使用了操作系统缓冲,它现在的速度要快得多!
    猜你喜欢
    • 1970-01-01
    • 2017-11-16
    • 2018-10-10
    • 2020-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2012-04-16
    相关资源
    最近更新 更多