【发布时间】:2023-03-28 04:43:01
【问题描述】:
我有一个很长的数字文件。类似于这个 perl 程序的输出:
perl -le 'print int(rand() * 1000000) for 1..10'
但更长——大约数百 GB。
我需要将此文件拆分为许多其他文件。出于测试目的,我们假设有 100 个文件,输出文件的编号是取模块号为 100 的。
对于普通文件,我可以简单地做到这一点:
perl -le 'print int(rand() * 1000000) for 1..1000' | awk '{z=$1%100; print > z}'
但是当我需要压缩分割的部分时我遇到了问题。通常,我可以:
... | awk '{z=$1%100; print | "gzip -c - > "z".txt.gz"}'
但是,当 ulimit 配置为允许打开的文件少于“分区”数时,awk 会中断:
awk: (FILENAME=- FNR=30) fatal: can't open pipe `gzip -c - > 60.txt.gz' for output (Too many open files)
这不会破坏正常的文件输出,因为 GNU awk 显然足够聪明,可以回收文件句柄。
您是否知道处理这种情况的任何方法(除了编写我自己的流拆分程序、实现缓冲和某种文件句柄池管理) - 即:拆分为多个文件,其中访问输出文件是随机的,并且动态压缩所有输出分区?
【问题讨论】:
-
ulimit -n列出的限制将成为您的瓶颈,无论您使用什么程序都没有执行“文件句柄管理”。我的 linux 系统显示 1024 个文件。你能把你的处理转移到另一个操作系统/机器上吗?祝你好运。 -
好吧,如果我要编写自己的程序,我可以确保我使用的文件句柄不超过
ulimit -n。 awk 会这样做,但只使用普通文件,而不是管道(出于可以理解的原因)。