计算超大文件中出现的字数(运行时内存耗尽)grep-o foo | wc-l

计算超大文件中出现的字数(运行时内存耗尽)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的块(或

有哪些选项可以在非常大的文件上进行字数统计

我相信整个文件在一行,这可能是问题的一部分,正如下面的一个答案所指出的

在本例中,我有一个1.7GB的xml文件,并试图快速计算其中的一些内容

我找到了这个帖子 这种方法在一定程度上适用于我

高达300Mb左右(40000次)的内存是不错的选择

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