我不确定这里发生了什么
#!/bin/bash
STRING_PREFIX="foo"
STRING_IDX="1,2,3,4,5"
declare -a STRING_ARRAY
main() {
assemble_strings
for i in "${STRING_ARRAY[@]}"; do
echo "TEST: $i"
done
}
assemble_strings() {
IFS=,
while IFS= read idx; do
STRING_ARRAY+=("${STRING_PREFIX}${idx}")
done < <(echo $STRING_IDX)
}
main
我期待一个包含5个字符串的数组,每个字符串前面加上'foo'。相反,我得到一个1字符串数组
TEST: foo1 2 3 4 5
对于奖励积分,我怎样才能完全避免循环?我无法弄清楚如何从bash中的表达式创建一个数组。
答案 0 :(得分:3)
首先:因为您将IFS=
放在read
的前面,之前的IFS=,
什么都不做(就read
而言)。
第二:因为您没有在-d ,
中设置read
,所以它使用默认值 - 换行符 - 值作为记录终止符。 (IFS
确定字段分隔符,而不是记录终结符;如果IFS值为空,则无论如何,您的记录中只有一个字段。因此,当你调用read
时,它会读取整个记录 - 直到新行 - 所以你的循环只运行一次。
一种方法,使用read -a
直接读取数组(在这种情况下,将整个输入流视为单个记录,字段用逗号分隔):
string_idx=1,2,3,4,5
string_prefix=foo
# use read to directly populate the array
IFS=, read -r -d '' -a string_array <<<"$string_idx"
# go back through and tack on prefixes
for idx in "${!string_array[@]}"; do
string_array[$idx]="${string_prefix}${string_array[$idx]}"
done
# print values
printf ' entry: %s\n' "${string_array[@]}"
另一个,对现有代码进行最小的更改 - 将输入流视为一系列单字段逗号分隔记录:
string_idx=1,2,3,4,5
string_prefix=foo
string_array=( )
while IFS= read -r -d , idx; do
string_array+=( "${string_prefix}${idx}" )
done <<<"$string_idx,"