如何在bash中设置数组元素的范围

3
我有一个由零组成的数组。
declare -a MY_ARRAY=( $(for i in {1..100}; do echo 0; done) )

如何将12-25日设置为“1”?我尝试过以下方法:
MY_ARRAY[12..25]=1
MY_ARRAY[12:25]=1
MY_ARRAY[12-25]=1  

全部不起作用...

范围12-25将是从另一个文件获取的变量。 我正在寻找一个简单的解决方案,最好不涉及循环。

请帮忙。


2
你必须注意,在形式为( ... )的数组声明中,索引编号从0开始,除非你指定了索引。例如( [3]="hello" )。因此,你的MY_ARRAY中第12个元素是${MY_ARRAY[11]} - Jdamian
3个回答

6

简单一句话:

for i in {12..25}; do MY_ARRAY[$i]=1; done

请参考页面Arrays获取更多操作示例。

如果起始和结束值存储在变量中,花括号扩展将不起作用。在这种情况下,您应该像这样使用for循环:

$ declare -i start=12
$ declare -i end=25
$ for ((i=$start;i<=$end;i++)); do MY_ARRAY[$i]=1; done

1
@once:正如您提到的,12和25是存储在变量中的数字,您需要使用循环。这是您需要使用的答案。 - anishsane

6
您可以在此处使用eval,方法如下:
eval MY_ARRAY[{12..25}]=1\;

如果你想知道被 eval 评估的内容,将 eval 替换为 echo
通常认为使用 eval 是不好的。但是这里使用 eval 应该是完全安全的。

另外一件事,

for i in {1..100}; do echo 0; done

也可以改写成

printf '%.1s\n' 0{1..100}

编辑: 对于存储在变量中的开始和结束,可以使用以下方法:

$ declare -i start=12
$ declare -i end=12
$ eval $(eval echo "MY_ARRAY[{$start..$end}]=1;")

但是在这种情况下,您应该真正使用循环。此答案仅用于演示/信息。


请再等一分钟。这里的 12..25 是硬编码的,还是从用户那里获取的?如果是后者,则使用 eval 可能不安全... - anishsane
谢谢! 在这种情况下,我不想使用循环, 但我不知道 eval, 为什么它是不可取的? - once
12..25 是从另一个文件中获取的变量,为什么这样做是不安全的? - once
请查看我提供的链接,“使用eval通常被认为是不可取的。” - anishsane
@once:OP 应该明确说明“不要求解决方案涉及循环”。 - Inian
3
那么携带12和25的变量应该声明为 declare -i start; declare -i end。另外,你需要知道的是,花括号扩展不能包含变量。例如,{$start..$end} 将不起作用。 - anishsane

2
declare -a MY_ARRAY=(
                      $(printf "%.2s" 0' '{1..11})    # 11 first zeroes
                      $(printf "%.2s" 1' '{12..25})   # 14 ones
                      $(printf "%.2s" 0' '{26..100})  # remaining zeroes
                    )

更新
如果有两个变量,分别为FromTo,它们的值分别为12和25:

declare -a MY_ARRAY=(
                       $( eval "{ printf %.2s 0_{1..$((From-1))};
                                  printf %.2s 1_{$From..$To};
                                  printf %.2s 0_{$((To+1))..100}; }" |
                                  tr _ ' '
                        )
                    )

1
请注意,数字12、25是从文件中获取的;即它们在一个变量中。花括号扩展将无法使用它们。但是OP在最初的问题中没有提到这一点。所以+1。 - anishsane
@anishsane,现在我已经为那种情况包含了另一段代码。 - Jdamian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接