2017-09-19 113 views
5

我想用以下用於產生獨特的作業,其中,{1}和{2}是唯一的元組:GNU並行組合數學,自變量的列表的使用多次

parallel echo {1} {2} ::: A B C D ::: A B C D 

例如,在蟒(itertools)提供了這樣一種組合學發生器:

permutations('ABCD', 2) 

AB AC AD BA BC BD CA CB CD DA DB DC


有沒有辦法通過bash直接實現它?或者GNU平行本身? 也許跳過多餘的工作?但是,如何檢查哪些參數組合已被使用。

parallel echo {= 'if($_==3) { skip() }' =} ::: {1..5} 
+1

一個選項是將數據存儲在數組中,並應用到其索引這裏詳細的策略:https://stackoverflow.com/a/21697322/5351549 – ewcz

+0

是ABCD的實際論點還是隻是佔有者?看到實際的參數列表將有所幫助,因爲適用於ABCD的解決方案可能不適用於其他類型的參數 – damienfrancois

回答

0

一個醜陋的解決方案:使用Python生成序列和--link選項(或--xapply):

$ parallel --xapply echo {1} {2} ::: $(python -c "from itertools import permutations ; print(' ::: '.join([' '.join(_) for _ in zip(*list(permutations('ABCD',2)))]))") 
A B 
A C 
A D 
B A 
B C 
B D 
C A 
C B 
C D 
D A 
D B 
D C 
0

您可以使用parallel兩次,如果你不介意:

# filter the first's parallel output for accepted combinations and pipe into a 2nd parallel 
parallel echo {1} {2} ::: a b c ::: a b c | awk '{ if ($1 != $2) {print $0}}' | parallel echo this is the actual {1} {2} 

# no one-liner for better maintenance 
parallel echo {1} {2} ::: a b c ::: a b c | awk '{ if ($1 != $2) {print $0}}' > myargs 
parallel --arg-file myargs echo {1} {2} 
rm myargs 

# Output is in both cases 
a b 
a c 
b a 
b c 
c a 
c b 
2

如果這些值是唯一的:

parallel echo {= 'if($arg[1] eq $arg[2]) { skip() }' =} ::: A B C D ::: A B C D 

或者更一般地說:

parallel echo \ 
    '{= my %seen; for my $a (@arg) { $seen{$a}++ and skip() } =}' \ 
    ::: A B C D ::: A B C D ::: A B C D 

如果你要正確對待AB作爲BA那麼這隻能運行組合之一:

parallel echo \ 
    '{= for my $t (2..$#arg) { if($arg[$t-1] ge $arg[$t]) { skip() } } =}' \ 
    ::: A B C D ::: A B C D ::: A B C D 

如果您使用這些很多,記得你可以使用--rpl來把你自己的替換字符串放在〜/ .parallel/config中

--rpl '{unique} my %seen; for my $a (@arg) { $seen{$a}++ and skip() }' 
--rpl '{choose_k} for my $t (2..$#arg) { if($arg[$t-1] ge $arg[$t]) { skip() } }' 

然後運行:

parallel echo {unique} ::: A B C D ::: A B C D ::: A B C D 
parallel echo {choose_k} ::: A B C D ::: A B C D ::: A B C D 
+0

我認爲這是正確的解決方案。我只想出了我的,因爲''parallel echo {='if($ arg [1] == $ arg [2]){skip()}'=} ::: ABCD ::: ABCD''沒有做的伎倆,我不知道「eq」。在zsh中,你必須編寫''「{= perl expression =}」''(即用雙引號括起來)。 – Rolf