2017-09-19 15 views
5

Tôi muốn sử dụng sau đây để tạo ra công ăn việc làm độc đáo, đó {1} và {2} là các bộ duy nhất:tổ hợp song song GNU, sử dụng danh sách các tham số nhiều lần

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

Ví dụ trong python (itertools) cung cấp một máy phát điện như combinatoric:

permutations('ABCD', 2) 

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


Có cách nào để triển khai trực tiếp thông qua bash không? Hoặc GNU song song chính nó? Có thể bỏ qua các công việc dư thừa bằng cách nào đó? Nhưng sau đó, làm cách nào tôi có thể kiểm tra các kết hợp tham số nào đã được sử dụng.

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

một lựa chọn sẽ được lưu trữ dữ liệu trong một mảng, và áp dụng cho các chỉ số của nó một chiến lược chi tiết tại đây: https://stackoverflow.com/a/21697322/5351549 – ewcz

+0

Are ABCD các đối số thực sự hoặc chỉ là người nắm giữ vị trí? Việc xem danh sách đối số thực sự sẽ giúp ích bởi vì các giải pháp hoạt động cho ABCD có thể không hoạt động đối với các loại đối số khác – damienfrancois

Trả lời

0

Một giải pháp xấu xí: sử dụng Python để tạo ra các trình tự và các --link tùy chọn (hoặc --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

Bạn có thể sử dụng parallel hai lần nếu bạn không nhớ:

# 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

Nếu các giá trị là duy nhất:

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

Hoặc tổng quát hơn:

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

Nếu bạn muốn điều trị AB như BA thì đây chỉ chạy một trong những kết hợp:

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 

Nếu bạn sử dụng các rất nhiều, nhớ bạn có thể sử dụng --rpl để tạo các chuỗi thay thế của riêng bạn bằng cách đặt mã này vào ~/.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() } }' 

Và sau đó chạy:

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

Tôi nghĩ đây là giải pháp đúng. Tôi chỉ đến với tôi vì '' echo echo {= 'if ($ arg [1] == $ arg [2]) {skip()}' =} ::: ABCD ::: ABCD'' không làm các trick và tôi đã không nhận thức được '' eq''. Trong zsh, bạn phải viết '' "{= perl expression =}" '' (tức là bao quanh với dấu ngoặc kép). – Rolf

Các vấn đề liên quan