确定 bash for 循环中的最后一次迭代

Sin*_*nan 9 bash

我有一个循环将一些行添加到配置文件中:

for i in ${H//,/ }
do
        sed -i "7i\                      host($i) or" $configPath/$g.conf
done
Run Code Online (Sandbox Code Playgroud)

$H 是逗号分隔的变量,例如:host1,host2,host4,host10

它返回以下内容:

                  host(host10) or
                  host(host4) or
                  host(host2) or
                  host(host1) or
Run Code Online (Sandbox Code Playgroud)

但我想要实现的是:

                  host(host10) or
                  host(host4) or
                  host(host2) or
                  host(host1)
Run Code Online (Sandbox Code Playgroud)

或相反亦然:

                  host(host1) or
                  host(host2) or
                  host(host4) or
                  host(host10)
Run Code Online (Sandbox Code Playgroud)

谁能帮助我找到正确的方向,我怎样才能做到这一点?

ori*_*ion 6

这个问题在大多数编程语言中都以相同的形式出现。以某种方式跳过后缀会很复杂。我不会讨论 shell 语法,只是用伪代码概述人们通常处理这个问题的方式:

# get it over with at the beginning:
print a[0] (no newline)
loop from a[1] onwards:
   print "or\n"
   print a[i]
print "\n" #terminate the last one
Run Code Online (Sandbox Code Playgroud)

这种情况可以通过循环索引或仅循环所有元素(跳过第一个)来工作,因为不涉及索引测试(如果语言支持对数组的直接迭代,例如 bash 和 python)。

你也可以从0开始,跳过最后一个,在循环外处理(上面的镜像),但是跳过最后一个通常比较脏,而且可能是不可能的(要跳过最后一个,你必须知道它是最后一个,但第一个总是可以立即跳过)。例如,如果您正在从流中读取元素,您无法提前知道哪一个是最后一个,而这种形式是唯一的选择

另一种方式:

# test a loop counter
N = length of array
loop with indices:
   if i==N-1:
      print a[i]
   else:
      print a[i],"or"
Run Code Online (Sandbox Code Playgroud)

请注意,这种情况需要您知道有多少个元素,并且它会不断测试索引。因此,您必须循环索引,或者单独跟踪索引(在循环之前设置 i=0,在循环内部设置 i++)。

我把这个写成一个菜谱,我将把 bash 的实现留给你。