替换 bash 中的嵌套 for 循环

时间:2021-01-22 09:50:52

标签: arrays bash for-loop

你能帮我摆脱嵌套的 for 循环吗? 数组可能一直在变化,截至目前我需要添加/删除 for 循环。是否可以用纯 bash 用更优雅的解决方案替换嵌套的 for 循环?

#!/bin/bash

i=0
array=(A B C)
places=3
word1=word1
word2=word2
arrC=${#array[*]}
while [ $i -lt $((arrC**places)) ]; do
    for a in ${!array[*]}; do
        for b in ${!array[*]}; do
            for c in ${!array[*]}; do
                echo "[$i] ${array[$a]}${word1}${array[$b]}${word2}${array[$c]}"
                i=$((i + 1))
            done
        done
    done
done

为了简单起见,我制作了 ABC 数组。这是数组的更多真实示例: 数组=(I i L l | \ / 1 !)

2 个答案:

答案 0 :(得分:1)

使用递归。

git config --global alias.fl 'log --graph --pretty=format:"%C(green)%h %C(yellow)%<(16,trunc)%aN %C(red)%<(12,trunc)%ar %C(reset)%<(135,trunc)%s"'

git fl

答案 1 :(得分:0)

查看使用递归函数以允许动态数量的 awk 循环的 for 解决方案。

但首先对输入参数进行一些修改(以便更容易地将信息传递到 awk);我们将用简单变量替换 bash 级数组(使用 : 作为本练习的分隔符):

array_s="A:B:C:D"
words_s="${word1}:${word2}"

一个awk想法:

awk -v places="${places}" -v words_s="${words_s}" -v array_s="${array_s}" '

function print_place(place,outstring, j, sfx) {        # define but do not pass "j" and "sfx"; 
                                                       # this designates these as local variables

if ( place > places )                                  # if we haveve exceeded the number of places ...
   { i++                                               # increment our counter
     printf "%s\n", outstring                          # print our string to stdout
     return                                            # and exit this invocation of the function
   }
if ( i > total ) return                                # if we have exceeded total number of outputs
                                                       # then exit this invocation of the function

sfx=""                                                 # default suffix is "" unless we
if ( place < places ) sfx=words[place]                 # have not reached the max number of places

for ( j=1 ; j<=n ; j++ )                               # loop through arr[] entries
    print_place(place+1,outstring arr[j] sfx)          # recursive function call for place+1; also pass along 
                                                       # our growing string
}

BEGIN { n=split(array_s,arr,":")                       # parse "array_s" into awk array "arr[]"
        m=split(words_s,words,":")                     # parse "words_s" into awak array "words[]"
        total=n**places                                # calculate total number of strings to print

        i=0                                            # init counter
        print_place(1,"")                              # call function
}
'

一些示例运行:

places=3
array_s="A:B:C"
words_s="word1:word2"

awk ...

Aword1Aword2A
Aword1Aword2B
Aword1Aword2C
Aword1Bword2A
Aword1Bword2B
Aword1Bword2C
...snip...
Cword1Cword2A
Cword1Cword2B
Cword1Cword2C                        # 27 lines of output

##############

places=2
array_s="A:B:C:D"
words_s="word1:word2"

awk ...

Aword1A
Aword1B
Aword1C
Aword1D
Bword1A
Bword1B
Bword1C
Bword1D
Cword1A
Cword1B
Cword1C
Cword1D
Dword1A
Dword1B
Dword1C
Dword1D                        # 16 lines of output

##############

places=4
array_s="A:B:C:D"
words_s="word1:word2:word3"

awk ...

Aword1Aword2Aword3A
Aword1Aword2Aword3B
Aword1Aword2Aword3C
Aword1Aword2Aword3D
Aword1Aword2Bword3A
Aword1Aword2Bword3B
Aword1Aword2Bword3C
Aword1Aword2Bword3D
Aword1Aword2Cword3A
Aword1Aword2Cword3B
...snip...
Dword1Dword2Cword3D
Dword1Dword2Dword3A
Dword1Dword2Dword3B
Dword1Dword2Dword3C
Dword1Dword2Dword3D                        # 256 lines of output