GNU Parallel: как начать строку замены номера задания с нуля

Я очень доволен скоростью параллельного использования GNU с разбиением файлов экспорта базы данных CSV с несколькими ГБ в управляемые куски. Однако проблема в том, что имена выходных файлов должны быть в формате some_table.csv.part_0000.csv и начать с нуля (инструмент импорта требует этого). Получить "0001" было непросто, но мне удалось использовать printf для достижения этой цели. Я не могу заставить декрет работать, хотя.

Моя команда:

FILE=some_table; parallel -v --joblog split.log --pipepart --recend '-- EOL\n' --block 25M "cat > $FILE.csv.part_$(printf "%04d"{#}).csv" :::: $FILE.csv

Делать такие вещи, как расширение выражения ($FILE.csv.part_$(({#}-1)).csv) не работает, потому что {#} смущает внутренняя оболочка. Так же PART=$(({#}-1)); cat > $FILE.csv.part_$PART.csv,

Какие-либо предложения?

1 ответ

Решение

Используйте конструкцию {= =}:

FILE=some_table;  parallel -v --joblog split.log --pipepart --recend '-- EOL\n' --block 25M "cat > $FILE.csv.part_"'{=$_=sprintf("%04d",$job->seq()-1)=}'".csv" :::: $FILE.csv

Если вы собираетесь его часто использовать, определите собственную строку замены, поместив ее в ~/.parallel/config:

--rpl '{0000#} $_=sprintf("%04d",$job->seq()-1)'

Затем используйте {0000#}:

seq 11 | parallel echo {0000#}

Если вы просто хотите, чтобы числа были фиксированной ширины (а не обязательно 4 цифры):

--rpl '{0#} $f="%0".int(1+log(total_jobs()-1)/log(10))."d";$_=sprintf($f,$job->seq()-1)'

Затем используйте {0#}:

seq 11 | parallel echo {0#}

На другом примечании: зачем вообще его сохранять в файлах? Почему бы не передать его напрямую импортеру базы данных и не использовать --retries/--retry-failed повторить неудачные куски?

Другие вопросы по тегам