2015-11-26 27 views
1

我正在用bash中的一系列嵌套for-loops循環遍歷n維空間。在bash中執行任意數量的嵌套循環

VAR1="a b c d e f g h i" 
VAR2="1 2 3 4 5 6 7 8 9" 
VAR3="a1 b2 b3 b4 b5 b6" 

for i1 in $VAR1; do 
    for i2 in $VAR2; do 
     for i3 in $VAR3; do 
      echo "$i1 $i2 $i3" 
     done 
    done 
done 

現在我得到更多的維度來遍歷,我意識到它會更容易/最好能夠通過指定變量的任意數量的循環。

如果我使用的是更復雜的編程語言,我可能會使用遞歸將列表傳遞給函數,關閉一個列表,遍歷它,遞歸調用每次循環中的函數,傳遞現在減少列表的清單,並隨時組裝n元組。

(我試圖僞代碼將是什麼樣子,但它傷害了我的腦袋想着遞歸和構建列表。)

function iterate_through(var list_of_lists) 
    this_list=pop list_of_lists 
    var new_list = [] 
    for i in this_list 
     new_list.push(i) 
     new_list.push(iterate_through(list_of_lists)) 
    # return stuff 
    # i gave up about here, but recursion may not even be necessary 

任何人有如何通過任意數量的完成迭代的建議vars在bash中?牢記目標是遍歷整個n維空間,並且迭代不一定是解決方案的一部分。

回答

1

parallel如果是可接受的,那麼可以簡化嵌套for環路

parallel -P1 echo {1} {2} {3} ::: $VAR1 ::: $VAR2 ::: $VAR3 

在一般情況下,它可能是或許可行的第一裝配該命令,然後執行它...

1

您可以使用遞歸計算笛卡爾積

以下腳本將完成具有可變長度輸入向量的作業:

#!/bin/bash 

dim=("a b c d e f g h i" "1 2 3 4 5 6 7 8 9" "a1 b2 b3 b4 b5 b6") 

function iterate { 

    local index="$2" 

    if [ "${index}" == "${#dim[@]}" ]; then 

     for ((i=0; i<=${index}; i++)) 
     do 
      echo -n "${items[$i]} " 
     done 
     echo "" 
    else 
     for element in ${dim[${index}]}; do 
      items["${index}"]="${element}" 
      local it=$((index+1)) 
      iterate items[@] "$it" 
     done 
    fi 
} 

declare -a items=("") 

iterate "" 0 

以下要點將輸入參數作爲所有維數組(空格分隔項):https://gist.github.com/bertrandmartel/a16f68cf508ae2c07b59