Bash脚本生成SQL CREATE TABLE语句丢失最后一列的问题排查
问题:Bash脚本处理CSV表头时丢失最后一列
我写了一个Bash脚本,用来从CSV文件生成PostgreSQL的CREATE TABLE语句,脚本代码如下:
#!/bin/bash # Check if the user provided a CSV file if [ $# -eq 0 ] then echo "No CSV file provided." exit 1 fi # Check if the CSV file exists if [ ! -f $1 ] then echo "CSV file does not exist." exit 1 fi # Get the table name from the CSV file name table_name=$(basename $1 .csv) # Extract the header row from the CSV file header=$(head -n 1 $1) # Split the header row into column names IFS=',' read -r -a columns <<< "$header" # Generate the PostgreSQL `CREATE TABLE` statement echo "CREATE TABLE $table_name (" for column in "${columns[@]}" do echo " $column TEXT," done echo ");"
当CSV文件的表头是aa,bb,cc时,生成的SQL语句里最后一列cc不见了。我做了两组测试:
直接遍历数组:
for a in "${array[@]}" do echo "$a" done
输出正常:
aaa bbb ccc
但在元素后追加内容时:
for a in "${array[@]}" do echo "$a SOMETHING" done
输出变成:
aaa SOMETHING bbb SOMETHING SOMETHING
请问这是什么原因导致的?
原因分析与解决方法
问题出在CSV文件的表头行末尾带有Windows风格的换行符\r(回车符)。
当用head -n 1读取表头时,最后一列cc的实际内容是cc\r。直接echo "$a"时,\r会把光标移到行首,但因为后面没有内容覆盖,看起来显示正常;但追加SOMETHING后,cc\r SOMETHING会触发光标回到行首,随后输出的 SOMETHING会把原来的cc覆盖,就出现了空前缀的情况。
解决方法
在读取表头后,先去掉末尾的\r字符,修改提取表头的代码:
# Extract the header row from the CSV file and remove Windows line ending header=$(head -n 1 "$1" | tr -d '\r')
或者用sed处理:
header=$(head -n 1 "$1" | sed 's/\r$//')
另外建议给脚本中的变量加上双引号(比如[ ! -f "$1" ]),避免文件名包含空格时出现异常。
内容的提问来源于stack exchange,提问作者Tomáš Vebr
相关产品推荐
相关产品推荐

