【发布时间】:2016-04-07 17:21:22
【问题描述】:
我有一个几千行的 ASCII 文件,由 bash 脚本一次处理一行。因为处理是令人尴尬的并行,我想将文件分成大小大致相同的部分,保留换行符,每个 CPU 内核一个部分。不幸的是,split r/numberOfCores 制作的文件后缀不容易被迭代。
split --numeric-suffixes=1 r/42 ... 生成文件foo.01、foo.02、...、foo.42,可以使用for i in `seq -w 1 42 ` 进行迭代,因为-w 添加了前导零)。但是如果 42 更改为小于 10 的值,文件仍然有前导零,但 seq 没有,所以它失败了。这种担忧是有道理的,因为现在有些 PC 的内核少于 10 个,有些超过 10 个。一个可怕的解决方法:
[[ $numOfCores < 10 ]] && optionForSeq="" || optionForSeq="-w"
简单的解决方案for f in foo.* 是有风险的:通配符可能匹配split 生成的文件以外的文件。
一种使后缀seq友好的丑陋方式,但风险相同:
split -n r/numOfCores infile foo.
for i in `seq 1 $numOfCores`; do
mv `ls foo.* | head -1` newPrefix.$i
done
for i in `seq 1 $numofCores`; do
... newPrefix.$i ...
done
是否有一种更简洁、更可靠的方法将文件拆分为 n 个部分,其中 1split 只进入新创建的目录?
(编辑:为了澄清“如果 42 更改为小于 10”,相同的代码应该在具有 8 个内核的 PC 和另一台具有 42 个内核的 PC 上运行。)
基于seq 的解决方案很笨拙。基于通配符的解决方案是有风险的。 split 有替代品吗? (带有行号的csplit 会更加笨拙。)gawk 单行?
【问题讨论】:
-
@Cyrus 将 9 替换为一个变量,然后花一分钟或更长时间尝试让它再次工作
-
var=9; eval echo {01..$var}他的示例不包含实变量。
标签: bash awk split parallel-processing ascii