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}
这将自动检测所需的前导零。
我对使用 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}
这将自动检测所需的前导零。