计算超大文件中出现的字数(运行时内存耗尽)grep-o foo | wc-l
有哪些选项可以在非常大的文件上进行字数统计 我相信整个文件在一行,这可能是问题的一部分,正如下面的一个答案所指出的 在本例中,我有一个1.7GB的xml文件,并试图快速计算其中的一些内容 我找到了这个帖子 这种方法在一定程度上适用于我 高达300Mb左右(40000次)的内存是不错的选择计算超大文件中出现的字数(运行时内存耗尽)grep-o foo | wc-l,grep,large-files,word-count,Grep,Large Files,Word Count,有哪些选项可以在非常大的文件上进行字数统计 我相信整个文件在一行,这可能是问题的一部分,正如下面的一个答案所指出的 在本例中,我有一个1.7GB的xml文件,并试图快速计算其中的一些内容 我找到了这个帖子 这种方法在一定程度上适用于我 高达300Mb左右(40000次)的内存是不错的选择 cat file.xml | grep -o xmltag | wc -l 但是如果超过这个大小,我就会“内存耗尽”试着像这样使用GNU Parallel。。。它将file.xml拆分为1MB的块(或
cat file.xml | grep -o xmltag | wc -l
但是如果超过这个大小,我就会“内存耗尽”试着像这样使用
GNU Parallel
。。。它将file.xml
拆分为1MB的块(或最近的新行上大约1MB的块),并将每个块传递给一个CPU核心以运行grep
,因此它不仅可以工作,而且应该工作得更快:
parallel --pipe grep -o xmltag < file.xml | wc -l
parallel--pipe grep-o xmltag
示例:为m个正则表达式生成n行
为大量regexp grep一个大文件的最简单解决方案是:
grep -f regexps.txt bigfile
或者,如果regexp是固定字符串:
grep -F -f regexps.txt bigfile
有两个限制因素:CPU和磁盘I/O
测量:如果grep占用超过90%的CPU(例如运行top时),则
CPU是一个限制因素,并行化将加快这一速度。如果
否则,磁盘I/O是限制因素,具体取决于磁盘
系统并行化的速度可能更快,也可能更慢。唯一知道的方法
肯定是要衡量的
如果CPU是限制因素,则应在regexp上执行并行化:
cat regexp.txt | parallel --pipe -L1000 --round-robin grep -f - bigfile
这将为每个CPU启动一个grep,并为每个CPU读取一次bigfile,
但是,由于这是并行进行的,除第一次读取外,所有读取都将被删除
缓存在RAM中。根据regexp.txt的大小,可能会更快地
使用--block 10m而不是-L1000。如果regexp.txt太大,无法放入
冲头,移除——循环并调整——L1000。这将导致大文件
要多读几遍
某些存储系统在读取多个数据块时性能更好
平行的这对于某些RAID系统和某些网络文件是正确的
系统。要并行读取大文件,请执行以下操作:
parallel --pipepart --block 100M -a bigfile grep -f regexp.txt
这将把bigfile分割成100MB的块,并在每个块上运行grep
这些大块。并行读取bigfile和regexp.txt
使用--fifo将两者结合起来:
file.xml中有多少新行?如果你的一行非常长,这也许可以解释为什么grep会以“grep:memory-detained”失败
解决方法是在无关紧要的地方\n引入。比如,在每次
之前,您是否尝试过这个grep-o'xmltag'file.xml | wc-l
Ref-Raj注释,您不应该将cat
与能够读取数据本身的程序一起使用。它减慢了程序的速度,使程序变得更复杂。是的,你需要把文件分成若干块。但是请注意,这种拆分可能是任意的,因此您的字数可能会增加(块数-1),因为每个块有一个拆分字
parallel --pipepart --block 100M -a bigfile --fifo cat regexp.txt \| parallel --pipe -L1000 --round-robin grep -f - {}
cat big.xml | perl -e 'while(sysread(STDIN,$buf, 32768)){ $buf=~s:</:\n</:; syswrite(STDOUT,$buf); }'
parallel -a big.xml --pipepart --recend '>' --recstart '<' --block 10M grep -o xmltag
parallel -a big.xml --pipepart --recend '</endrecord>' --block 10M grep -o xmltag