【问题标题】:GNU Parallel: How to start job number replacement string at zeroGNU Parallel:如何从零开始作业号替换字符串
【发布时间】:2016-09-15 15:01:41
【问题描述】:

我对使用 GNU 并行将多 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) 之类的操作不起作用,因为 {#} 会混淆内部子外壳。 PART=$(({#}-1)); cat > $FILE.csv.part_$PART.csv也是如此。

有什么建议吗?

【问题讨论】:

  • 您想对这些 CSV 文件做什么?换句话说,你为什么要分裂呢?
  • 这些是平面文件导出,将使用 mysqlimport 加载到 AWS RDS。通过将它们分成块,事务大小更加合理,并且更容易在错误时恢复。这是大意:(nerds.airbnb.com/mysql-in-the-cloud-at-airbnb)
  • 这不是split的工作吗?
  • 同意,使用split(或awk)代替parallel

标签: bash gnu-parallel


【解决方案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 重试失败的块?

如果你想要它用于工作槽:

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

你也可以使用动态替换字符串:

--rpl '{(0+?)%} $l=length $$1; $_=sprintf("%0${l}d",$job->slot())'
--rpl '{(0+?)#} $l=length $$1; $_=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}

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

【讨论】:

  • 非常感谢@Ole Tange,这太棒了。我怀疑 {= =} 是一个可能的解决方案,但我发现它的文档很难使用(并且完全错过了关于 --rpl 的部分)。
  • @Excalibur 通过重写文档来回报您,这样您会发现它更易于使用。
  • 谢谢!如果 Parallel 的未来版本能够内置 {0#}、{00#}、{000#}、...、语法,那就太好了。
  • @OleTange 我们怎样才能为工作槽号完成同样的事情?
  • 带有数字 > 1 的 -n 选项会产生奇怪的结果:seq 1024 | parallel -n 64 echo {0000#} 会产生:0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065 0065...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多