GNU Parallel:如何从零开始作业编号替换字符串

GNU Parallel: How to start job number replacement string at zero

我对使用 GNU parallel 将多 GB 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) 之类的事情是行不通的,因为 {#} 会混淆内部子 shell。 PART=$(({#}-1)); cat > $FILE.csv.part_$PART.csv.

也是

有什么建议吗?

使用 {= =} 结构:

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 重试失败的块?

如果你想要它的职位:

parallel --rpl '{0000%} $_=sprintf("%04d",$job->slot())' echo {0000%} ::: {1..100}

您还可以使用动态替换字符串:

--rpl '{(0+?)%} $l=length $; $_=sprintf("%0${l}d",$job->slot())'
--rpl '{(0+?)#} $l=length $; $_=sprintf("%0${l}d",$job->seq())'

parallel echo {0%} ::: {1..100}
parallel echo {0#} ::: {1..100}
parallel echo {00%} ::: {1..100}
parallel echo {00#} ::: {1..100}
parallel echo {000%} ::: {1..100}
parallel echo {000#} ::: {1..100}

从版本 20210222 开始,您可以:

parallel --plus echo {0%} ::: {1..100}
parallel --plus echo {0#} ::: {1..100}

这将自动检测所需的前导零。