如何在bash中创建一系列列表(或类似的)?

时间:2017-01-31 19:40:37

标签: arrays bash list loops

我想在bash中迭代几个列表。现在我有

blank=True

这不起作用。有没有办法在bash中列出列表,数组数组或列表数组?

我想迭代list1,然后是list1中的listitems。然后遍历list2和list2中的列表项。

2 个答案:

答案 0 :(得分:4)

我将缺少的dodone添加到您的代码中:

array=("list1item1 list1item2" "list2item list2item2")

for list in "${array[@]}"
do
    for item in $list
    do
        echo $item
    done
done

它产生了预期的输出:

list1item1
list1item2
list2item
list2item2

我不清楚这与你的期望有何不同。

但是,这不是将列表嵌套到数组中的一般方法,因为它依赖于IFS分隔的内部列表。 Bash不提供嵌套数组;数组严格来说是一个字符串数组,没有别的。

您可以使用间接(${!v})并将变量名称存储到外部数组中,尽管它有点难看。一个不太丑陋的变体是以下,它依赖于namerefs;它将适用于最近的bash版本:

array=(list1 list2)
list1=("list 1 item 1" "list 1 item 2")
list2=("list 2 item 1" "list 2 item 2")
for name in "${array[@]}"; do
  declare -n list=$name
  for item in ${list[@]}; do
    echo "$item"
  done
done

输出:

list 1 item 1
list 1 item 2
list 2 item 1
list 2 item 2

答案 1 :(得分:0)

缺乏声誉,无法对米色发表评论...

现在可以创建列表列表,或多或少,并且由于rici的答案(从bash4.4起),避免使用名称引用,这要归功于数组引用扩展:@Q。例如:

declare -a list1=("one" "two three")
declare -a list2=("four five" "six")
declare -a listOfLists=("(${list1[*]@Q})" "(${list2[*]@Q})")
echo "${#listOfLists[@]}"
2

如您所见,listOfLists正确扩展为2个元素。现在的好处是,由于有了@Q,作为列表的listOfLists内部的元素也可以正确扩展为每个2个元素(而不是不使用@Q时将具有3个元素):

declare -a sameAsList1="${listOfLists[0]}"; declare -a sameAsList2="${listOfLists[1]}"
echo "${#sameAsList1[@]}" ; echo "${#sameAsList2[@]}"
2
2
declare -p sameAsList1 && declare -p list1
declare -a sameAsList1=([0]="one" [1]="two three")
declare -a list1=([0]="one" [1]="two three")

我们终于有了列表列表!