То, что я имею в виду, является выводом первой команды, вход следующего.
Это корректно. Однако в Ваших двух примерах, различие - это grep
действия на его входе, тогда как du
не делает. При передаче по каналу работ как ожидалось, только если первая команда дает что-то стандартному выводу и вторым взятиям что-то от стандартного входа, в этом случае эти два потока будут соединены через "канал". Можно узнать, возможно ли это путем поиска "стандартного входа" и "стандартного вывода" в страницах справочника команд.
Использование - канал:
cat 2011.psv | parallel --pipe -l 50000000 ./carga_postgres.sh
Это требует, чтобы./carga_postgres.sh читал из stdin а не из файла и медленно для версии Параллели GNU <20130222.
Если Вам не нужны точно 50 000 000 строк - блок быстрее:
cat 2011.psv | parallel --pipe --block 500M ./carga_postgres.sh
Это передаст блоки разделения приблизительно 500 МБ на \n.
Я не знаю то, что содержит./carga_postgres.sh, но мое предположение - он, содержит psql с паролем имени пользователя. В этом случае Вы могли бы хотеть использовать GNU SQL (который является частью Параллели GNU):
cat 2011.psv | parallel --pipe --block 500M sql pg://user:pass@host/db
Главное преимущество - то, что Вы не должны сохранить временные файлы, но можете сохранить все в памяти/каналах.
Если./carga_postgres.sh не может читать из stdin, но должен читать из файла, можно сохранить его в файл:
cat 2011.psv | parallel --pipe --block 500M "cat > {#}; ./carga_postgres.sh {#}"
Большие задания часто приводят половину к сбою пути через. Параллель GNU может помочь Вам путем повторного выполнения неудавшихся заданий:
cat 2011.psv | parallel --pipe --block 500M --joblog my_log --resume-failed "cat > {#}; ./carga_postgres.sh {#}"
Если это перестало работать затем, можно повторно выполнить вышеупомянутое. Это пропустит блоки, которые уже обрабатываются успешно.
Я нашел ответы отправленными здесь, чтобы быть путем к комплексу, таким образом, я спросил относительно Переполнения стека, и я получил этот ответ:
Если Вы используете GNU split
, можно сделать это с --filter
опция
‘-filter=command’
При использовании этой опции, вместо того, чтобы просто писать в каждый выходной файл, пишут через канал в указанную команду оболочки для каждого выходного файла. команда должна использовать переменную среды $FILE, которая установлена на другое название выходного файла каждого вызова команды.
Можно создать сценарий оболочки, который создает файл, и запустите carga_postgres.sh в конце в фоновом режиме
#! /bin/sh
cat >$FILE
./carga_postgres.sh $FILE &
и используйте тот сценарий в качестве фильтра
split -l 50000000 --filter=./filter.sh 2011.psv
Альтернатива созданию split
печать, которую состоят в том, чтобы обнаружить имена файлов, когда файлы готовы. На Linux можно использовать inotify средство, и конкретно inotifywait
утилита.
inotifywait -m -q -e close_write --format %f carga | parallel ./carga_postgres.sh &
split -l 50000000 2011.psv carga/2011_
Необходимо будет уничтожить inotifywait
вручную. Уничтожение его автоматически немного трудно, потому что существует потенциальное состояние состязания: если Вы уничтожаете его как только split
концы, это, возможно, получило события, о которых это еще не сообщило. Чтобы удостовериться, что обо всех событиях сообщают, считайте файлы соответствия.
{
sh -c 'echo $PPID' >inotifywait.pid
exec inotifywait -m -q -e close_write --format %f carga
} | tee last.file \
| parallel ./carga_postgres.sh &
split -l 50000000 2011.psv carga/2011_
(
set carga/2011_??; eval "last_file=\${$#}"
while ! grep -qxF "$last_file" last.file; do sleep 1; done
)
kill $(cat inotifywait.pid)
Почему бы не использовать --pipe И --pipepart с GNU Parallel? Это устраняет лишнюю кошку и запускает прямое чтение из файла на диске:
parallel --pipe --pipepart -a 2011.psv --block 500M ./carga_postgres.sh