在KSH脚本中使用AWK拆分CSV文件时遇空值重定向错误求助
解决KSH中AWK拆分CSV文件时的空重定向错误
问题概述
在KSH脚本中使用AWK拆分大型CSV文件时,运行以下代码出现错误:
# Split file awk -v l=${FILE_LINE_COUNT_LIMIT} '(NR==1){header=$0;next} (NR%l==2) { close(file); file=sprintf("%s.%0.5d.csv",FILENAME,++c) sub(/csv[.]/,"",file) print header > file } {print > file}' ${FTP_FILE}
错误信息:
awk: cmd. line:9: (FILENAME=test101001.csv FNR=2) fatal: expression for `>' redirection has null string value
错误原因
- 变量初始化时机错误:首次处理数据行(NR=2)时,
file变量尚未赋值——原脚本的NR%l==2条件仅当FILE_LINE_COUNT_LIMIT的值恰好让NR除以l余2时才会触发,若l大于2,NR=2时不会进入分支创建文件,导致print > file中file为空。 - 拆分条件逻辑错误:原条件
NR%l==2无法实现每l行数据拆分一次的需求,未考虑表头占1行的偏移量。 - 文件名替换正则不准确:
/csv[.]/可能错误匹配文件名中间的csv.字符串,而非仅替换原文件末尾的.csv后缀。
解决方案
修正AWK逻辑,确保file变量提前初始化,调整拆分条件,优化文件名处理:
修正后的完整代码
# Split large CSV file with header preserved FILE_LINE_COUNT_LIMIT=1000 # 自定义每个小文件的数据行数 FTP_FILE="test101001.csv" # 目标CSV文件名 awk -v l="${FILE_LINE_COUNT_LIMIT}" ' (NR == 1) { header = $0 # 初始化第一个输出文件 c = 1 file = sprintf("%s.%0.5d.csv", FILENAME, c) sub(/\.csv$/, "", file) # 移除原文件名末尾的.csv后缀 print header > file next } # 每处理l条数据行(偏移表头的1行)就新建文件 (NR - 1) % l == 0 { close(file) c++ file = sprintf("%s.%0.5d.csv", FILENAME, c) sub(/\.csv$/, "", file) print header > file } { print > file }' "${FTP_FILE}"
关键修正点
- 提前初始化文件变量:在处理表头时直接创建第一个输出文件,确保后续所有行处理时
file均有有效值。 - 修正拆分条件:使用
(NR-1) % l == 0,以数据行序号(减去表头的1行)为基准,每l行拆分一次。 - 优化文件名处理:
sub(/\.csv$/, "", file)精准匹配原文件名末尾的.csv后缀,避免错误替换。 - 变量加双引号:
"${FILE_LINE_COUNT_LIMIT}"和"${FTP_FILE}"避免文件名或变量含空格时出现解析错误。
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

