2017-09-19 98 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