如何迭代先前未存储为变量的多个 bash 数组和元素?

如何迭代先前未存储为变量的多个 bash 数组和元素?

我试图解决的问题

我试图解决的问题是能够迭代两个 bash 数组中的元素以及单个元素,这样这些元素之前不会存储为变量;当场宣布:

for e in "$(seq -f "number-%g" 0 4) $(seq -f "number-%g" 5 9) number-10" ; do echo $e; done

当我执行此操作时,我看到:

$ for e in "$(seq -f "number-%g" 0 4) $(seq -f "number-%g" 5 9) number-10" ; do echo $e; done
number-0 number-1 number-2 number-3 number-4 number-5 number-6 number-7 number-8 number-9 number-10

似乎所有内容都在同一行上打印出来。

我查阅过的资源

我已阅读并尝试了这些页面上的资源:

我尝试过的实验

实验1

这将数组存储在中间变量中:

seq1="$(seq -f "number-%g" 0 4)"
seq2="$(seq -f "number-%g" 5 9)"
elem="number-10"
all=("${seq1[@]}" "${seq2[@]}" "${elem}")

打印出来的结果是:

$ for e in $all; do echo $e; done
number-0
number-1
number-2
number-3
number-4

这似乎没有选取第二个数组或最后一个元素。

实验2

在这里,我显式存储两个数组,而不是使用 生成它们seq,但是,我 1.) 不想根据“我试图解决的问题”存储此问题的中间变量,2.) 我想使用该seq命令反对明确声明数组。

$ seq1=("number-0" "number-1" "number-2" "number-3" "number-4")
$ seq2=("number-5" "number-6" "number-7" "number-8" "number-9")
$ all=("${seq1[@]}" "${seq2[@]}" "number-10")

将其与“number-10”一起打印出来会产生:

$ for e in "${all[@]}"; do echo $e; done
number-0
number-1
number-2
number-3
number-4
number-5
number-6
number-7
number-8
number-9
number-10

我期待听到一些 bash 技巧!谢谢!

答案1

那么,我们来谈谈这个:

$ seq1="$(seq -f "number-%g" 0 4)"
$ seq2="$(seq -f "number-%g" 5 9)"
$ elem="number-10"
$ all=("${seq1[@]}" "${seq2[@]}" "${elem}")
$ declare -p all
declare -a all=([0]=$'number-0\nnumber-1\nnumber-2\nnumber-3\nnumber-4' [1]=$'number-5\nnumber-6\nnumber-7\nnumber-8\nnumber-9' [2]="number-10")
$ for e in $all; do echo $e; done
number-0
number-1
number-2
number-3
number-4

注意declare -p——检查变量的内容非常方便。

all是一个大批多变的。当您将其取消引用时$all,您实际上正在做的事情${all[0]}——即仅检索第一的元素。

看到这个all数组只有 3 个元素了吗?和seq1变量seq2不是数组,它们是普通的“标量”变量。与上一段类似,您可以使用数组元素语法来引用标量变量:

$ x="hello world"
$ declare -p x
declare -- x="hello world"
$ echo "$x"
hello world
$ echo "${x[0]}"
hello world
$ echo "${x[1]}"

$ echo "${x[*]}"
hello world
$ echo "${x[@]}"
hello world

如果你想执行外部命令并捕获输出行数,使用mapfile命令。您还需要使用流程替代调用外部命令。

$ unset seq1 seq2 all
$ mapfile -t seq1 < <(seq -f "number-%g" 0 4)
$ mapfile -t seq2 < <(seq -f "number-%g" 5 9)
$ all=("${seq1[@]}" "${seq2[@]}" "${elem}")
$ declare -p all
declare -a all=([0]="number-0" [1]="number-1" [2]="number-2" [3]="number-3" [4]="number-4" [5]="number-5" [6]="number-6" [7]="number-7" [8]="number-8" [9]="number-9" [10]="number-10")
$ printf "%s\n" "${all[@]}"
number-0
number-1
number-2
number-3
number-4
number-5
number-6
number-7
number-8
number-9
number-10

要在 bash 中生成此序列而不使用任何外部工具,请使用支撑扩张

$ all=( "number-"{0..10} )
$ declare -p all
declare -a all=([0]="number-0" [1]="number-1" [2]="number-2" [3]="number-3" [4]="number-4" [5]="number-5" [6]="number-6" [7]="number-7" [8]="number-8" [9]="number-9" [10]="number-10")

相关内容