如何在Bash脚本中打印由大括号扩展命令生成的数组?
问题描述
我尝试用以下bash脚本通过大括号扩展定义数组:
#!/bin/bash declare -a arr=({1..$(wc mylist.txt | cut -d " " -f 3)}) for i in "${arr[@]}"; do echo $i; done
其中wc mylist.txt | cut -d " " -f 3用于获取文件行数(实际结果为7),期望生成包含1到7的数组,等价于declare -a arr=({1..7}),最终数组应为declare -a arr=(1 2 3 4 5 6 7),遍历后输出每行一个数字。
但实际输出却是:
{1..7}
如何才能得到正确的输出?
解决方案
原方法失效原因
bash的扩展执行顺序是大括号扩展优先于命令替换,当解析{1..$(wc ...)}时,大括号扩展阶段还未执行命令替换,无法识别里面的数字,因此会把整个{1..7}(命令替换后的结果)当成单个字符串存入数组,遍历自然只输出这一个元素。
方法1:用seq命令生成序列
seq可以直接生成连续数字序列,结合命令替换赋值给数组,同时用wc -l直接获取行数,比原cut写法更可靠:
#!/bin/bash line_count=$(wc -l < mylist.txt) arr=($(seq 1 $line_count)) for i in "${arr[@]}"; do echo $i done
方法2:用C风格循环填充数组
通过循环逐个添加元素到数组,逻辑直观且无安全风险:
#!/bin/bash arr=() line_count=$(wc -l < mylist.txt) for ((i=1; i<=line_count; i++)); do arr+=($i) done for i in "${arr[@]}"; do echo $i done
方法3:用eval强制扩展(不推荐)
如果非要保留大括号扩展的写法,可以通过eval让bash重新解析命令替换后的表达式,但注意:若文件行数来自不可信来源,eval可能引入安全风险:
#!/bin/bash line_count=$(wc -l < mylist.txt) eval "arr=({1..$line_count})" for i in "${arr[@]}"; do echo $i done
内容的提问来源于stack exchange,提问作者RaxusOp 1
相关产品推荐
相关产品推荐

