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
повторить неудачные куски?