我想用以下bash脚本构建一个单词列表但是append不起作用:
declare -a NODES=()
cat $1 | while read line;do
for word in $line; do
NODES+=("$word")
echo $word
done
done
echo "Nodes: ${NODES[@]}"
我得到了输出:
node01
node02
node03
node04
Nodes:
运行脚本:
$ bash myscript.sh nodes_list
nodes_list文件: NODE01 NODE02 node03 node04
答案 0 :(得分:5)
你遇到了一个与管道有关的经典问题 - 管道的每一面都在它自己的子shell中执行,所以你使用的数组超出范围,其内容在循环后消失。
你的问题可以简单地解决(你也摆脱了对cat
无用的使用):
nodes=() # no need to use declare here, use lowercase variable names
while read -r line; do # -r switch is almost always what you want
for word in $line; do
nodes+=("$word")
echo "$word" # always quote your variables!
done
done < "$1" # use redirection instead of a pipe to avoid creating a subshell
echo "Nodes: ${nodes[@]}"
答案 1 :(得分:1)
根据您的用例和问题,Tom Fenech的答案很好,但您也可以使用IFS创建一个数组:
#!/bin/bash
declare nodes=( $(<"$1") )
for (( i = 0; i < ${#nodes[@]}; ++i )); do
echo "line: ${i}: ${nodes[$i]}"
done
将之前的代码保存为toto.bash
,它将回显:
$ ./toto.bash toto.bash
line: 0: #!/bin/bash
line: 1: declare
line: 2: nodes=(
line: 3: $(<"$1")
line: 4: )
line: 5: for
line: 6: ((
line: 7: i
line: 8: =
line: 9: 0;
line: 10: i
line: 11: <
line: 12: ${#nodes[@]};
line: 13: ++i
line: 14: ));
line: 15: do
line: 16: echo
line: 17: "line:
line: 18: ${i}:
line: 19: ${nodes[$i]}"
line: 20: done
如果你需要逐行分割(例如:获取包含每一行的数组),你可以这样做:
OIFS=$IFS
IFS=$'\n'
declare nodes=( $(<"$1") )
IFS=$OIFS
OIFS用于恢复之前的IFS,以避免不必要的副作用。