如何用sed为无分隔符定长记录插入分隔符并存入bash数组
定长无分隔符记录拆分到Bash数组的解决方案
方案1:GNU Awk FIELDWIDTHS 实现(最适配定长字段场景)
GNU Awk 原生提供FIELDWIDTHS变量专门处理定长字段解析,不受sed反向引用最多9组的限制,可支持任意数量、任意宽度的字段配置:
# 示例配置:前3个字段宽度为10字符,后续按需指定3字符宽度字段 FIELD_SPEC="10 10 10 3 3 3 3 3 3" record=($(echo "$line" | awk -v FIELDWIDTHS="$FIELD_SPEC" '{OFS=" "; $1=$1; print $0}'))
如果后续所有剩余字段均为固定3字符宽度,可动态生成宽度配置,无需手动枚举全部字段:
total_len=${#line} remaining_len=$(( total_len - 3 * 10 )) FIELD_SPEC="10 10 10 $(printf '3%.0s' $(seq 1 $(( remaining_len / 3 )) ))" record=($(echo "$line" | awk -v FIELDWIDTHS="$FIELD_SPEC" '{OFS=" "; $1=$1; print $0}'))
方案2:Perl unpack 实现(支持通配符规则,满足一次性处理需求)
Perl的unpack函数完全对应C语言scanf的定长读取逻辑,支持批量重复规则,你需要的3*格式可以直接用(A3)*实现,无需提前知道总字段数:
# A10代表10位ASCII字符,(A3)*代表剩余所有内容按3位一组拆分 record=($(echo "$line" | perl -ne 'print join(" ", unpack("A10 A10 A10 (A3)*", $_))'))
该方案为一次性处理逻辑,无需循环,适配任意长度的定长记录。
方案3:纯Bash参数扩展实现(无外部依赖)
如果不允许调用awk、perl等外部工具,可通过bash原生参数扩展实现拆分:
# 按顺序定义所有字段的宽度 widths=(10 10 10 3 3 3 3 3 3 3 3 3) offset=0 record=() for w in "${widths[@]}"; do record+=("${line:offset:w}") (( offset += w )) done
该方案逻辑简单无依赖,性能足以应对常规数据处理场景。
内容的提问来源于stack exchange,提问作者Gunther Schadow
相关产品推荐
相关产品推荐

