Параллельная 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 процессов.

Другие вопросы по тегам