修改文本文件而不读入内存

时间:2014-07-07 16:20:02

标签: linux text-files

我试图想出一种修改文本文件(特别是删除特定行)的方法,而无需将大部分文件读入内存或重写整个文件。这里讨论的文件大于主内存大约15-50 Gigs。

P.S。我正在使用Linux。

3 个答案:

答案 0 :(得分:1)

你不会绕过制作一个新文件,所以只需咬紧牙关就可以了。将grep与适当的选项一起使用,并将结果传递给第二个文件:

$ grep -fv patternsToExcludeFromInput input > output

另一种方法是将模式作为示例放入哈希表(Perl),字典(Python)或unordered_map(C ++)中,并处理输入文件的每一行以查找匹配项。

如果没有匹配项,请将该行打印到标准输出流(可以将其输出到常规文件)。您的内存使用量主要限于哈希表和您要查询的输入行。

答案 1 :(得分:0)

您可以在“rw”模式下打开文件,并使用fseek,fread,fwrite来读取/写入部分文件。你必须注意不要覆盖尚未阅读的部分。因此,要删除您正在读取和写入的行,要插入您向后读取和写入的行(从文件末尾开始)。

示例

要从文件开头删除前100个字节,您可以执行以下操作:

FILE *fp = fopen(filename,"rw");
size_t BLOCK_SIZE = 1024;
char buffer[BLOCK_SIZE];
size_t offset = 100;
fseek(fp,0,SEEK_END);
size_t length = ftell(fp);
for (size_t i=0; i< (length-offset+BLOCK_SIZE-1) / BLOCK_SIZE; ++i) {
  fseek(fp,i*BLOCK_SIZE + offset,SEEK_SET);
  size_t count = fread(fp,buffer,sizeof(char),BLOCK_SIZE);
  fseek(fp,i*BLOCK_SIZE,SEEK_SET);
  fwrite(fp,buffer,sizeof(char),count);
}

答案 2 :(得分:0)

如果文件比内存大,sed是你的朋友。它充当旧文件和新文件之间的过滤器,最后,您只需将新文件重命名为旧名称。新手的语法有点奇怪,但它非常强大,能够按编号,正则表达式或范围选择行,并应用插入,删除或字符串替换。