如何不使用临时变量,仅用Shell参数扩展给数组元素前后加字符串?
能否不借助临时变量,仅用Shell参数扩展给数组所有元素同时添加前后缀?
假设有数组:
a=(1 2 3)
我们已经知道单独给元素加前缀或后缀的参数扩展写法:
- 给每个元素添加前缀
[:
$ echo ${a[@]/#/[} [1 [2 [3
- 给每个元素添加后缀
]:
$ echo ${a[@]/%/]} 1] 2] 3]
目前同时添加前后缀(把元素包裹成[x])的常规做法需要借助临时变量:
$ a=(1 2 3) tmp=(${a[@]/#/[}) echo ${tmp[@]/%/]} [1] [2] [3]
那是否支持类似以下嵌套参数扩展的写法(直接把加前缀后的数组结果作为加后缀扩展的输入)?
# 以下写法无效!!! ${ /%/]} ^^^^^^^^^^^^^ (${a[@]/#/[}) # 尝试嵌套参数扩展,将加前缀后的数组作为输入进行后缀扩展
结论与替代方案
在Bash中,不支持直接嵌套数组的参数扩展,没法把${a[@]/#/[}的结果直接作为另一个参数扩展的输入。不过有几种无需临时变量的替代方法:
方案1:用printf命令(最简洁)
利用printf的循环输出特性,一次性完成前后缀拼接:
a=(1 2 3) printf '[%s] ' "${a[@]}" && echo
输出结果:
[1] [2] [3]
末尾的&& echo是为了补充换行,避免输出停留在行尾。
方案2:结合外部工具实现
如果一定要基于参数扩展的思路,可以借助xargs和sed完成,但依赖外部工具:
a=(1 2 3) echo "${a[@]/#/[}" | xargs -n1 | sed 's/$/]/' | xargs
方案3:利用子shell隔离临时变量
虽然不是纯参数扩展,但可以用子shell处理,临时变量不会污染当前shell环境:
a=(1 2 3) echo $(tmp=("${a[@]/#/[}" ); echo "${tmp[@]/%/]}")
总结:纯参数扩展的嵌套写法在Bash中不可行,但用printf等方法可以更简洁地实现需求,且无需临时变量。
内容的提问来源于stack exchange,提问作者wolfrevo
相关产品推荐
相关产品推荐

