Bash 中的可变列表或数组结构?我怎样才能轻松地附加到它?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2013396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:50:23  来源:igfitidea点击:

Mutable list or array structure in Bash? How can I easily append to it?

arraysbashscripting

提问by Joe

I'm trying to collect string values in a bash script. What's the simplest way that I can append string values to a list or array structure such that I can echo them out at the end?

我正在尝试在 bash 脚本中收集字符串值。将字符串值附加到列表或数组结构以便我可以在最后回显它们的最简单方法是什么?

回答by Paused until further notice.

$ arr=(1 2 3)
$ arr+=(4)
$ echo ${arr[@]}
1 2 3 4

Since Bash uses sparse arrays, you shouldn't use the element count ${#arr}as an index. You can however, get an array of indices like this:

由于 Bash 使用稀疏数组,因此不应使用元素计数${#arr}作为索引。但是,您可以获得这样的索引数组:

$ indices=(${!arr[@]})

回答by Ignacio Vazquez-Abrams

foo=(a b c)
foo=("${foo[@]}" d)
for i in "${foo[@]}"; do echo "$i" ; done

回答by codaddict

To add to what Ignacio has suggested in another answer:

添加 Ignacio 在另一个答案中的建议:

foo=(a b c)
foo=("${foo[@]}" d) # push element 'd'

foo[${#foo[*]}]="e" # push element 'e'

for i in "${foo[@]}"; do echo "$i" ; done

回答by ennuikiller

The rather obscure syntax for appending to the end of an array in bash is:

在 bash 中附加到数组末尾的相当晦涩的语法是:

myarr[${#myarr[*]}]=”$newitem”

回答by ghostdog74

$ for i in "string1" "string2" "string3"
> do
> array+=($i)
> done
$ echo ${array[@]}
string1 string2 string3

回答by theoden8

Though the question is answered and is pretty old, I'd like to share a namespace-solution as it works significantly faster than any other ways except for ennukiller's answer (on my 100k lines tests it won ~12 secs against my ~14 secs, whereas list-append solution would take a few minutes).

虽然这个问题已经得到解答并且已经很老了,但我想分享一个命名空间解决方案,因为它比ennukiller的答案以外的任何其他方式都快得多(在我的 100k 行测试中,它比我的 ~14 赢得了 ~12 秒秒,而列表附加解决方案需要几分钟)。

You can use the following trick:

您可以使用以下技巧:

# WORKS FASTER THAN THESE LAME LISTS! ! !
size=0;while IFS= read -r line; do
    echo $line
    ((++size))
    eval "SWAMP_$size='$line'"
done

Or you can do the following:

或者您可以执行以下操作:

#!/bin/bash
size=0
namespace="SWAMP"

ArrayAppend() {
    namespace=""
    # suppose array size is global
    new_value=""
    eval "${namespace}_$size=''"
    eval "echo $${namespace}_$size"
    ((++size))
}

ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"

As long as the interpreter is in tag list, here's a link for object oriented bash.

只要解释器​​在标签列表中,这里就是面向对象 bash的链接。