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 в кусках. Вы должны заметить, что порядок во втором столбце (и остальной части файла) сохраняется.