Python 3.x 将数据块从大型文件写入新文件的最快方法是什么?
假设我有一个文件,它只是非常相似的块的重复(下面显示的简化示例)。提取某些块并将其写入单独文件的最快方法是什么?所有块都以相同的数字开始\n。输入文件可以有超过一百万个步骤,每个块可以有几千个原子。因此,我不想读入(巨大的)文件或完全循环,因为我只需要有限的步骤(例如每1000个步骤)。我正在考虑bash脚本(sed或head | tail with grouping)、python(内存映射和用regex存储块)或awk()。有没有我不知道的方法或语言? 多谢各位Python 3.x 将数据块从大型文件写入新文件的最快方法是什么?,python-3.x,awk,bigdata,Python 3.x,Awk,Bigdata,假设我有一个文件,它只是非常相似的块的重复(下面显示的简化示例)。提取某些块并将其写入单独文件的最快方法是什么?所有块都以相同的数字开始\n。输入文件可以有超过一百万个步骤,每个块可以有几千个原子。因此,我不想读入(巨大的)文件或完全循环,因为我只需要有限的步骤(例如每1000个步骤)。我正在考虑bash脚本(sed或head | tail with grouping)、python(内存映射和用regex存储块)或awk()。有没有我不知道的方法或语言? 多谢各位 6 step 1 C
6
step 1
C 9.0000000 8.3380808 9.0000001
C 9.0000000 9.6619194 8.9999999
H 8.0768455 7.7678700 9.0000001
H 9.9231545 10.2321301 9.0000001
H 8.0768455 10.2321301 9.0000001
H 9.9231545 7.7678700 9.0000001
6
step 2
C 9.00000000 8.33808080 9.00000010
C 9.00000000 9.66191940 8.99999990
H 8.07684550 7.76787000 9.00000010
H 9.90912982 10.23213008 8.83969637
H 8.09087028 10.23213012 9.16030383
H 9.92315450 7.76787000 9.00000010
6
step 3
C 9.00000000 8.33808080 9.00000010
C 9.00000000 9.66191940 8.99999990
H 8.07684550 7.76787000 9.00000010
H 9.86748170 10.23213006 8.68426301
H 8.13251850 10.23213014 9.31573717
H 9.92315450 7.76787000 9.00000010
我写了一个小POC。这接近你想要的吗
awk '
/^[0-9]/ { print "skipping " $0; next; }
/step / { fn = sprintf("%s.%s", $1, $2); print "assigned fn = ", fn; }
/^ *[A-Z]/ { print $0 >> fn; print "sent ", $0, " to ", fn; }
' infile
输出:
skipping 6
assigned fn = step.1
sent C 9.0000000 8.3380808 9.0000001 to step.1
sent C 9.0000000 9.6619194 8.9999999 to step.1
sent H 8.0768455 7.7678700 9.0000001 to step.1
sent H 9.9231545 10.2321301 9.0000001 to step.1
sent H 8.0768455 10.2321301 9.0000001 to step.1
sent H 9.9231545 7.7678700 9.0000001 to step.1
skipping 6
assigned fn = step.2
sent C 9.00000000 8.33808080 9.00000010 to step.2
sent C 9.00000000 9.66191940 8.99999990 to step.2
sent H 8.07684550 7.76787000 9.00000010 to step.2
sent H 9.90912982 10.23213008 8.83969637 to step.2
sent H 8.09087028 10.23213012 9.16030383 to step.2
sent H 9.92315450 7.76787000 9.00000010 to step.2
skipping 6
assigned fn = step.3
sent C 9.00000000 8.33808080 9.00000010 to step.3
sent C 9.00000000 9.66191940 8.99999990 to step.3
sent H 8.07684550 7.76787000 9.00000010 to step.3
sent H 9.86748170 10.23213006 8.68426301 to step.3
sent H 8.13251850 10.23213014 9.31573717 to step.3
sent H 9.92315450 7.76787000 9.00000010 to step.3
结果文件:
$: cat step.1
C 9.0000000 8.3380808 9.0000001
C 9.0000000 9.6619194 8.9999999
H 8.0768455 7.7678700 9.0000001
H 9.9231545 10.2321301 9.0000001
H 8.0768455 10.2321301 9.0000001
H 9.9231545 7.7678700 9.0000001
$: cat step.2
C 9.00000000 8.33808080 9.00000010
C 9.00000000 9.66191940 8.99999990
H 8.07684550 7.76787000 9.00000010
H 9.90912982 10.23213008 8.83969637
H 8.09087028 10.23213012 9.16030383
H 9.92315450 7.76787000 9.00000010
$: cat step.3
C 9.00000000 8.33808080 9.00000010
C 9.00000000 9.66191940 8.99999990
H 8.07684550 7.76787000 9.00000010
H 9.86748170 10.23213006 8.68426301
H 8.13251850 10.23213014 9.31573717
H 9.92315450 7.76787000 9.00000010
请注意,您的示例在第一节中没有前导空格,但在后续节中有一个前导空格
根据需要进行调整,希望有帮助。请看,您对任务的描述实际上没有帮助。如果每个块的字节数相同,您可以
mmap
文件并计算所需的每个块的开始和结束。在那里搜索,读取准确的字节数,并对每个块重复。如果字节数不同。。。然后,您必须遍历整个文件。如果块大小相同,可能是具有dd
的内容?我只需要有限的步骤。您能否显示所提供样本数据的预期输出?另外,这些是\n
s字符串还是换行符?在后一种情况下,不需要在示例数据中显示它们,请将它们编辑掉。6是下一块中的数据行数吗?这当然解决了问题,但是没有回答哪种方法最快的问题?只读取一次文件并在执行过程中处理任务的方法通常比任何需要多次传递的方法都要快。类似于awk
的东西将比bash
脚本快,假设使用read
纯bash
。通过管道并行运行多个可执行文件,您可能会获得更快的结果,但是必须反复执行head | tail
才能获得所有部分,所以不要这样做。如果您只是想写入文件,我认为内存映射没有什么价值。我的答案是最快的,这在我的例子中是隐含的——很抱歉不清楚。