Bash中如何按\n分隔符拆分字符串并存入数组
问题原因
你原来的脚本不生效有两个核心原因:
- Bash默认的字段分隔符
IFS包含空格、制表符、换行三类字符,直接执行命令替换赋值数组时,会优先按空格拆分内容,和你要按\n拆分的需求不符 - 不带参数的
echo不会解析字符串里的字面量\n为实际换行符,输出时\n会作为普通字符保留,无法作为拆分标记
正确实现方案
方案1:使用readarray/mapfile(推荐,无副作用)
这是Bash原生专门用来按行读入数组的命令,不会误拆空格,兼容性覆盖绝大多数主流发行版的Bash版本:
test="BOB_ENV: DEV\nStorage: @MOM.KV(Name=lol-lol;SCT=c-s-string)\nConn__name: ab-cb-ac-one.sb.w.net\nTest: Test" # echo -e 负责把字面量\n转为实际换行,readarray按换行拆分存入数组 readarray -t arr < <(echo -e "$test") # 验证:输出数组索引为1的元素 echo "${arr[1]}"
运行后输出结果为Storage: @MOM.KV(Name=lol-lol;SCT=c-s-string),符合预期。
参数说明:
-t会自动移除每行末尾的换行符,避免数组元素携带多余空行;使用进程替换< <(...)而非管道,是为了避免子shell问题导致数组在当前shell环境下无法访问。
方案2:临时修改IFS适配老版本Bash
如果使用的Bash版本较老不支持readarray,可以临时修改IFS指定分隔符为换行,同时关闭通配符展开避免特殊字符被错误解析:
test="BOB_ENV: DEV\nStorage: @MOM.KV(Name=lol-lol;SCT=c-s-string)\nConn__name: ab-cb-ac-one.sb.w.net\nTest: Test" # 仅对当前赋值语句临时生效IFS配置,不会修改全局IFS值 IFS=$'\n' arr=($(echo -e "$test")) echo "${arr[1]}"
注意这里必须用$'\n'的ANSI-C转义写法代表实际换行符,不能直接写"\n"。
避坑点
- 变量展开时要加双引号,避免Shell提前按默认规则拆分内容
- 不要用管道写法
echo -e "$test" | readarray -t arr,管道右侧运行在子shell中,当前shell无法获取到赋值后的数组 - 必须给echo加
-e参数,否则字符串里的\n不会被解析为实际换行
内容的提问来源于stack exchange,提问作者JS noob
相关产品推荐
相关产品推荐

