Bash中的可变列表或数组结构?我如何轻松地附加到它?


69

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

Answers:


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

由于Bash使用稀疏数组,因此您不应将元素计数${#arr}用作索引。但是,您可以获取如下所示的索引数组:

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


4

要添加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

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

2

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

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

正如丹尼斯·威廉姆森(Dennis Williamson)的答案所指出的那样,在某些情况下这是不正确的。bash数组稀疏,索引$ {#myarr [*]}可能不是最后一个索引。
埃文·克拉尔

0

尽管这个问题已经回答并且很老了,但我还是想分享一个命名空间解决方案,因为它的工作速度比任何其他方式都要快,除了ennukiller的回答(在我的10万行测试中,它相对于〜14赢得了约12秒的时间)秒,而列表附加解决方案则需要几分钟)。

您可以使用以下技巧:

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

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

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

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

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

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


不要eval用于分配(尤其是在用户输入时)!您的代码会受到代码注入的影响,并且非常不安全(因此被破坏)!所以……甚至比la脚的名单还残酷:)
gniourf_gniourf

顺便说一句,如果您的唯一目标是将文件逐行插入数组中,且Bash≥4,则应使用mapfilemapfile -t lines < file
gniourf_gniourf

不过,如果您提出要求,我可以向您展示一种鲜为人知的eval安全使用方式……
gniourf_gniourf 2015年

@gniourf_gniourf,当然。我想看看。
theoden8

1
mapfile是Bash内置函数(您有一个标记为bash的问题)。
gniourf_gniourf
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.