You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell脚本操作MariaDB建表插数报cut、SQL语法等错误求助

问题现象

运行Shell脚本实现MariaDB自动建表、插入CSV统计数据时抛出以下错误:

ERROR 1366 (22007) at line 1: Incorrect integer value: '' for column `a4_mgarr048_count`.`airline`.`total` at row 1
cut: option requires an argument -- 'f'

ERROR 1366 (22007) at line 1: Incorrect integer value: '' for column `a4_mgarr048_count`.`airline`.`total` at row 1
cut: you must specify a list of bytes, characters, or fields

at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(name varchar(255), tot                                                                                                                                                        al int)' at line 1

原问题脚本如下:

readarray -d , -t header <<< "gender,state,municipality,season,continent,elective,f1,airline"
for (( n=0; n < ${#header[@]} +1 ; n++))
do
  mysql -D a4_mgarr048_count -e "create table ${header[n]} (name varchar(255),total int);"
done

readarray -d , -t header <<< "gender:4,state:6,municipality:7,season:8,continent:9,elective:10,f1:11,airline:12"
for  (( n=0; n < ${#header[@]} +1; n++))
do
  readarray -d : -t fields <<< ${header[n]}
  while read line 
  do
    mysql -D a4_mgarr048_count -e "insert into ${fields[0]} values ('$(echo $line | cut -d, -f2)','$(echo $line | cut -d, f1)')"
    done < <(cat /root/mgarr048.csv | cut -d, -f${fields[1]} | sort | uniq -c |sed -e 's/^\s*//g' -e 's/ /,/g')
    done
错误原因排查
  • 数组循环越界:Bash数组下标从0开始,${#header[@]}返回数组元素总个数,循环条件写n < ${#header[@]} +1会导致最后一次循环读取到下标等于数组长度的空元素,执行建表语句时表名为空,直接触发SQL语法错误。
  • cut命令参数书写错误:插入语句中第二个cut命令写为cut -d, f1,缺少参数前缀-,导致cut无法识别字段参数,直接抛出参数缺失错误,且该命令无输出,传给int类型total字段的是空字符串,触发1366类型不匹配错误。
  • 不可见字符导致SQL语法异常:使用readarray -d ,分割字符串时,here-string末尾自带的换行符会被存入最后一个数组元素中,导致表名、字段名夹带换行符,最终SQL语句出现异常断行(报错中total被拆分为带大段空白的断行内容就是该问题导致)。
  • 冗余管道增加额外开销:使用cat 文件 | cut的写法属于不必要的管道调用,会额外创建进程。
修复方案

修正后的可运行脚本如下:

#!/bin/bash
# 建表逻辑
readarray -d , -t header <<< "gender,state,municipality,season,continent,elective,f1,airline"
for (( n=0; n < ${#header[@]} ; n++))
do
  # 去除元素中夹带的换行、空白字符
  table_name=$(echo "${header[n]}" | tr -d '\n\r ')
  mysql -D a4_mgarr048_count -e "create table if not exists ${table_name} (name varchar(255),total int);"
done

# 数据插入逻辑
readarray -d , -t header <<< "gender:4,state:6,municipality:7,season:8,continent:9,elective:10,f1:11,airline:12"
for  (( n=0; n < ${#header[@]}; n++))
do
  readarray -d : -t fields <<< ${header[n]}
  table_name=$(echo "${fields[0]}" | tr -d '\n\r ')
  col_num=$(echo "${fields[1]}" | tr -d '\n\r ')
  while read line 
  do
    # 修正cut参数,按uniq -c输出顺序匹配字段:f1是计数(total)、f2是维度值(name)
    val_name=$(echo "$line" | cut -d, -f2)
    val_total=$(echo "$line" | cut -d, -f1)
    mysql -D a4_mgarr048_count -e "insert into ${table_name} (name, total) values ('${val_name}', ${val_total});"
  done < <(cut -d, -f${col_num} /root/mgarr048.csv | sort | uniq -c | sed -e 's/^\s*//g' -e 's/ /,/g')
done

修复点说明:

  • 调整循环边界为n < ${#header[@]},避免数组越界读取空值;新增if not exists判断,避免重复建表报错。
  • 补全cut命令缺失的-前缀,修正参数错误。
  • 对所有从数组读取的表名、列号做过滤,删除换行、回车、空格等不可见字符,避免SQL异常断行。
  • 插入SQL显式指定字段顺序,确保字符串类型的name、整数类型的total和传入值一一对应,避免类型不匹配错误。
  • 去掉冗余的cat管道,cut直接读取目标CSV文件,减少不必要的进程开销。

内容的提问来源于stack exchange,提问作者Michael Garrido

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:45:38