Использование GNU Parallel With Split
Я загружаю довольно гигантский файл в базу данных postgresql. Для этого я сначала использую split
в файле, чтобы получить файлы меньшего размера (по 30Gb каждый), а затем загружаю каждый меньший файл в базу данных с помощью GNU Parallel
и psql copy
.
Проблема в том, что для разделения файла требуется около 7 часов, а затем он начинает загружать файл на ядро. Мне нужен способ сообщить split
распечатать имя файла для вывода std каждый раз, когда он заканчивает запись файла, поэтому я могу передать его на Parallel
и он начнет загружать файлы в то время split
завершить запись, Что-то вроде этого:
split -l 50000000 2011.psv carga/2011_ | parallel ./carga_postgres.sh {}
Я прочитал man-страницы split
, и я ничего не могу найти. Есть ли способ сделать это с помощью split
или любого другого инструмента?
Ответы
Ответ 1
Вы можете позволить параллелировать расщепление:
<2011.psv parallel --pipe -N 50000000 ./carga_postgres.sh
Обратите внимание, что manpage рекомендует использовать --block
над -N
, это по-прежнему будет разделять входные данные в разделителях записей, \n
по умолчанию, например:
<2011.psv parallel --pipe --block 250M ./carga_postgres.sh
Тестирование --pipe
и -N
Вот тест, который разбивает последовательность из 100 чисел на 5 файлов:
seq 100 | parallel --pipe -N23 'cat > /tmp/parallel_test_{#}'
Проверить результат:
wc -l /tmp/parallel_test_[1-5]
Вывод:
23 /tmp/parallel_test_1
23 /tmp/parallel_test_2
23 /tmp/parallel_test_3
23 /tmp/parallel_test_4
8 /tmp/parallel_test_5
100 total
Ответ 2
Если вы используете GNU split
, вы можете сделать это с помощью опции --filter
"- фильтр = команда
С помощью этой опции вместо того, чтобы просто записывать каждый выходной файл, пишите через канал в указанную команду оболочки для каждого выходного файла. команда должна использовать переменную среды $FILE, для которой задано другое имя выходного файла для каждого вызова команды.
Вы можете создать оболочку script, которая создает файл и запустит carga_postgres.sh в конце в фоновом режиме
#! /bin/sh
cat >$FILE
./carga_postgres.sh $FILE &
и используйте script как фильтр
split -l 50000000 --filter=./filter.sh 2011.psv