Shell读取CSV文件时echo拼接变量与固定字符串输出异常排查
问题原因
- 第一,变量处理的语法错误:你写的
变量=("${变量%$'\r'}") | sed ...格式完全不符合bash赋值逻辑。管道符会为两侧的命令分别创建独立子shell,左侧的变量赋值仅在子shell中生效,无法作用于当前主shell,同时sed的处理结果也没有被赋值回目标变量,你写的去空格、去回车的几行代码完全没有实际效果。 - 第二,行尾回车符导致输出覆盖:你读取的CSV是Windows格式文件,每行末尾为
\r\n换行符,由于去回车的代码未生效,App_Id变量末尾残留了\r(回车)控制符。输出时\r会让光标直接跳转到当前行的行首,后续的输出内容会从行首开始覆盖之前已经打印的内容,最终就出现了你看到的第二行输出混乱的问题。
修正后的代码示例
{ read header while IFS="," read -r Role_Collections Role_Name Role_Template App_Id do # 正确处理:先移除行尾回车,再去首尾空格,最后将结果赋值回原变量 Role_Collections=$(echo "${Role_Collections%$'\r'}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') Role_Name=$(echo "${Role_Name%$'\r'}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') Role_Template=$(echo "${Role_Template%$'\r'}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') App_Id=$(echo "${App_Id%$'\r'}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') echo "Role coll=${Role_Collections}|${Role_Name}|${Role_Template}|${App_Id}" echo "${Role_Name} -to-role-collection ${Role_Collections} -of-app ${App_Id} -of-role-template ${Role_Template}" done } < "csvfile.csv"
如果想要更高性能的处理,也可以用bash内置的参数扩展实现去空格,无需调用外部sed命令:
# 定义内置去空格函数 trim() { local input="$*" # 去除开头空格 input="${input#"${input%%[![:space:]]*}"}" # 去除结尾空格 input="${input%"${input##*[![:space:]]}"}" echo -n "$input" } { read header while IFS="," read -r Role_Collections Role_Name Role_Template App_Id do Role_Collections=$(trim "${Role_Collections%$'\r'}") Role_Name=$(trim "${Role_Name%$'\r'}") Role_Template=$(trim "${Role_Template%$'\r'}") App_Id=$(trim "${App_Id%$'\r'}") echo "Role coll=${Role_Collections}|${Role_Name}|${Role_Template}|${App_Id}" echo "${Role_Name} -to-role-collection ${Role_Collections} -of-app ${App_Id} -of-role-template ${Role_Template}" done } < "csvfile.csv"
内容的提问来源于stack exchange,提问作者Lord OfTheRing
相关产品推荐
相关产品推荐

