Параллельная GNU: совместное использование --pipe и args
С помощью --pipe -N<int>
Я могу отправить определенное количество строк в качестве ввода задания, начатого parallel
, Но как мне выполнить несколько заданий с разными аргументами :::
на каждом куске?
Давайте возьмем этот маленький входной файл:
A B C
D E F
G H I
J K L
Кроме того, давайте определим, чтобы передать каждую две линии к parallel
работа. И на них команда cut -f<int>
должен быть выполнен с номером столбца, заданным в качестве входных аргументов для параллельного типа ::: {1..3}
Таким образом, для данного примера вывод будет выглядеть следующим образом
A
D
B
E
C
F
G
J
H
K
I
L
Я пробовал эту команду:
cat input.txt|parallel --pipe -N2 'cut -f{1}' ::: {1..3}
Но вывод таков:
A
D
I
L
Что мне не хватает?
плавник плавник
1 ответ
Это:
cat input.txt|parallel --pipe -N2 'cut -f{1}' ::: {1..3}
читает 2 записи из каждого источника ввода. Это более понятно, если вы делаете:
$ cat input.txt|parallel --pipe -v -N2 'cut -f{}' ::: {1..3}
cut -f1 -f2
cut: only one type of list may be specified
Try 'cut --help' for more information.
cut -f3
I
L
GNU Parallel соединяет каждый аргумент с блоком. То, что вы ищете, больше похоже на --tee
где каждый блок отправляется на каждую команду. --tee
однако не разделяет входные данные на блоки, а отправляет все входные данные команде. Так что, возможно, мы можем объединить два:
doit() { parallel --pipe -N2 -v cut -f$@; }
export -f doit
cat input.txt|parallel --pipe --tee -v doit {} ::: {1..3}
Или вы можете перевернуть заказ (это, вероятно, менее эффективно):
doit() { parallel -v --pipe --tee cut -f{} ::: {1..3}; }
export -f doit
cat input.txt|parallel --pipe -N2 -v doit
Удалить -v
когда вы довольны тем, что запускается.
--tee
очень эффективно (1-2 Гбайт / с с --pipe
, 2-3 Гбайт / с с --pipepart
), но его недостатком является то, что он запускает все задания параллельно: так что если у вас вместо {1..3} есть 10000 значений, то он запустит 10000 процессов.