Использование 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