Bash下按制表符拆分字符串为数组并处理字段的问题
解决Bash中按制表符拆分字符串时保留空字段的问题
需求说明
需要处理来自MySQL执行结果的字符串,满足以下要求:
- 按制表符(
\t)拆分为数组,必须保留连续制表符对应的空字段(包括开头、中间、结尾的空字段) - 字段内的转义序列
\t和\n需转换为真实的制表符和换行符 - 将字符串中的
\r\n替换为\n
原方案的问题
原函数使用read -a结合IFS=$'\t'拆分,但read命令默认会忽略开头的空字段、合并连续的分隔符,导致空字段丢失,无法满足需求。
解决方案
利用awk的字段拆分特性(默认保留所有空字段)处理拆分和转义,再通过空字符(\0)作为临时分隔符读取到数组中,确保包含换行符的字段也能正确捕获。适配Bash 4.2.46版本的实现如下:
function MySQL__Untreated_String_To_Treated_Array() { local pstr_untreated_string="$1" gtReturnFonction=() # 1. 替换\r\n为\n,处理\r为\n;2. awk拆分制表符、处理转义、用\0分隔输出 local processed_output processed_output=$(printf "%s" "$pstr_untreated_string" | sed -e 's/\r\n/\n/g' -e 's/\r/\n/g' | awk ' BEGIN { FS = "\t" OFS = "\0" # 用空字符作为字段分隔符,避免与字段内容冲突 } { for (i=1; i<=NF; i++) { # 转换字段内的转义序列 gsub(/\\t/, "\t", $i) gsub(/\\n/, "\n", $i) # 输出字段,最后一个字段后加换行 printf "%s%s", $i, (i == NF ? "\n" : OFS) } } ') # 读取用\0分隔的字段到数组,保留字段内的换行符 while IFS= read -r -d '' field; do gtReturnFonction+=("$field") done <<< "$processed_output" # 处理输入结尾为空字段的情况(如输入以制表符结尾) if [[ "$processed_output" =~ $'\0'$'\n'$ ]]; then gtReturnFonction+=("") elif [[ -z "$processed_output" ]]; then gtReturnFonction+=("") fi }
测试验证
测试用例1:空输入
MySQL__Untreated_String_To_Treated_Array "" echo "数组长度:${#gtReturnFonction[@]}" # 输出:1 echo "第一个字段:'${gtReturnFonction[0]}'" # 输出:''
测试用例2:单个制表符输入
MySQL__Untreated_String_To_Treated_Array $'\t' echo "数组长度:${#gtReturnFonction[@]}" # 输出:2 echo "字段1:'${gtReturnFonction[0]}'" # 输出:'' echo "字段2:'${gtReturnFonction[1]}'" # 输出:''
测试用例3:两个连续制表符输入
MySQL__Untreated_String_To_Treated_Array $'\t\t' echo "数组长度:${#gtReturnFonction[@]}" # 输出:3 echo "字段1:'${gtReturnFonction[0]}'" # 输出:'' echo "字段2:'${gtReturnFonction[1]}'" # 输出:'' echo "字段3:'${gtReturnFonction[2]}'" # 输出:''
最终测试用例
输入:$'\t_SECOND_FIELD_\t\t_FOURTH_\\t_FIELD\t_FIFTH_\n_FIELD_\t'
执行函数后,数组内容:
- 索引0:空字符串
- 索引1:
_SECOND_FIELD_ - 索引2:空字符串
- 索引3:
_FOURTH_ _FIELD(\t转换为真实制表符) - 索引4:
_FIFTH_换行_FIELD_(\n转换为真实换行) - 索引5:空字符串
内容的提问来源于stack exchange,提问作者Tom's
相关产品推荐
相关产品推荐

