Bash
Параллельно
Поиск…
Вступление
Работа в GNU Linux может быть распараллелирована с использованием GNU-параллелизма. Задание может быть одной командой или маленьким скриптом, который должен быть запущен для каждой из строк на входе. Типичным входом является список файлов, список хостов, список пользователей, список URL-адресов или список таблиц. Задание также может быть командой, которая считывает из трубы.
Синтаксис
- parallel [options] [команда [аргументы]] <list_of_arguments>
параметры
вариант | Описание |
---|---|
-jn | Запуск n заданий параллельно |
-k | Сохраняйте тот же порядок |
-X | Множество аргументов с заменой контекста |
--colsep regexp | Разделить ввод на регулярное выражение для позиционных замещений |
{} {.} {/} {/.} {#} | Запасные струны |
{3} {3.} {3/} {3/.} | Позиционные строки замены |
-S sshlogin | Example: [email protected] |
--trc {}.bar | Сокращение для --transfer --return {} .bar --cleanup |
--onall | Запустите заданную команду с аргументом во всех sshlogins |
--nonall | Запустите заданную команду без аргументов во всех sshlogins |
--pipe | Сплит stdin (стандартный ввод) для нескольких заданий. |
--recend str | Запишите концевой разделитель для --pipe. |
--recstart str | Секунда начала записи для --pipe. |
Параллелизировать повторяющиеся задачи в списке файлов
Многие повторяющиеся задания могут выполняться более эффективно, если вы используете больше ресурсов своего компьютера (например, ЦП и ОЗУ). Ниже приведен пример параллельной работы нескольких заданий.
Предположим, что у вас есть < list of files >
, например вывод из ls
. Кроме того, пусть эти файлы сжаты bz2, и на них должен работать следующий порядок задач.
- Декомпрессируйте файлы
bzcat
с помощьюbzcat
в stdout - Grep (например, фильтр) с определенным ключевым словом (-ами) с использованием
grep <some key word>
- Выполните вывод, который будет объединен в один файл
gzip
используяgzip
Выполнение этого с помощью цикла while может выглядеть так:
filenames="file_list.txt"
while read -r line
do
name="$line"
## grab lines with puppies in them
bzcat $line | grep puppies | gzip >> output.gz
done < "$filenames"
Используя GNU Parallel, мы можем запускать сразу три параллельных задания, просто делая
parallel -j 3 "bzcat {} | grep puppies" ::: $( cat filelist.txt ) | gzip > output.gz
Эта команда проста, кратки и эффективна, когда количество файлов и размер файла являются большими. -j 3
запускаются parallel
, опция -j 3
запускает 3 параллельных задания, а вход в параллельные задания берется в :::
. Выход в конечном итоге подается на gzip > output.gz
Параллелизировать STDIN
Теперь давайте представим, что у нас есть 1 большой файл (например, 30 ГБ), который нужно преобразовать, построчно. Скажем, у нас есть скрипт, convert.sh
, который выполняет эту <task>
. Мы можем передать содержимое этого файла в stdin для параллельного ввода и работы с такими кусками , как
<stdin> | parallel --pipe --block <block size> -k <task> > output.txt
где <stdin>
может происходить из чего-либо, такого как cat <file>
.
В качестве воспроизводимого примера наша задача будет nl -n rz
. Возьмите любой файл, мой будет data.bz2
и передайте его в <stdin>
bzcat data.bz2 | nl | parallel --pipe --block 10M -k nl -n rz | gzip > ouptput.gz
В приведенном выше примере используется <stdin>
из bzcat data.bz2 | nl
, где я включил nl
как доказательство того, что окончательный выходной output.gz
будет сохранен в том порядке, в котором он был получен. Затем parallel
делит <stdin>
на куски размером 10 МБ, и для каждого фрагмента он передает его через nl -n rz
где он просто добавляет числа, правильно оправданные (подробнее см. nl --help
). Опции --pipe
parallel
split <stdin>
на несколько заданий, а -- block
определяет размер блоков. Опция -k
указывает, что упорядочение должно поддерживаться.
Ваш конечный результат должен выглядеть примерно так:
000001 1 <data>
000002 2 <data>
000003 3 <data>
000004 4 <data>
000005 5 <data>
...
000587 552409 <data>
000588 552410 <data>
000589 552411 <data>
000590 552412 <data>
000591 552413 <data>
В моем исходном файле было 552 413 строк. Первый столбец представляет собой параллельные задания, а второй столбец представляет собой исходную нумерацию строк, которая была передана parallel
в кусках. Вы должны заметить, что порядок во втором столбце (и остальной части файла) сохраняется.