Bash脚本编程:在for循环中填充数组

4

我试图创建一个存储了一些值的数组,但是我不知道该怎么做。我尝试了下面的代码,但它并没有起作用。

我的代码:

i=0
for c in colors; do
array[$i]=$c
echo {$c[$i]}
i=`expr $i + 1`
done

注意: "colors" 是一种类似于 "ps -ef" 命令的命令,返回一个值列表。例如,它具有 "blue,red,yellow" 值。

colors= 'ps -ef | grep colors'

重要的是确切地返回colors列表的方式。如果它们一行一个被返回,那么有比字符串分割更可靠的方法来获取它们(就像你正在做的,也是你所接受的答案所做的,这将导致例如将颜色*改变为当前目录中的文件列表,或将颜色light magenta转换为两个条目,即lightmagenta)。 - Charles Duffy
顺便提一下,在bash中,(( ++i ))是编写i=$(expr $i + 1)的现代方式。 - Charles Duffy
...而你的代码中唯一完全无法运行的问题(与最佳实践违规不同)是写成了{$c[$i]}而不是${c[$i]},以及in colors而不是in $colors - Charles Duffy
另外,正如http://mywiki.wooledge.org/ProcessManagement文档所述,您应该优先使用`pgrep`命令而不是对`ps`输出进行grep。 - Charles Duffy
2个回答

5

您可以使用此脚本在循环中填充数组:

array=()
for c in $colors; do
    array+=( "$c" )
done

甚至更简单:
array=( $(command) )

如果我们假设字符串分割是一个已知的过程,那么最佳实践方法是,如果输入是逐行进行的,则使用while/read循环来拆分元素--这样我们就不会有全局扩展、基于IFS的拆分或其他类似的副作用。 - Charles Duffy
你们有“更简单”的命令的例子吗?像这样的: "array=($("ps -ef|grep pmon"))"? - AloneInTheDark
2
@AloneInTheDark,不要使用引号,只需使用array=( $(ps -ef | grep ...) ) -- 但这是一个不好的做法,有几个原因。 - Charles Duffy
1
@AloneInTheDark:当你使用array=( $(command) )时,每个元素都由空格或换行符分隔。因此,如果元素本身包含空格,则会被拆分为多个数组元素。有处理这种情况的方法;例如适当使用IFS,就像Charles的答案中所述。 - anubhava

5

如果你的颜色是一行一个,当你展开存储它们的未引用变量时,你可能会丢失信息(删除空格和换行之间的区别,扩展glob字符等)。

不要这样做。相反,请遵循BashFAQ #1

colors=()
while IFS='' read -r color; do
    colors+=( "$color" )
done < <(get-color-list)

如果你只想获取每行中的特定列,read 可以为你进行列拆分,使其更易于赋值。

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