在巨大的文本文件上使用“ head”或“ tail”-19 GB


15

我在查看很大的文本文件的块时遇到了问题。该文件大约19 GB,显然太大,无法通过任何传统方式查看。

我曾尝试head 1tail 1head -n 1tail -n 1)有两个命令以各种方式(获取在中间一张),没有运气管道连接到一起。我的运行Ubuntu 9.10的Linux机器无法处理此文件。

我该如何处理该文件?我的最终目标是磨合45000000和45000100行。


考虑编写一个快速的Python脚本来读取行并打印我需要归档的行,但是我可以想象这需要很长时间...
nicorellius 2012年

所有的线都一样长吗?
Paul

@Paul-不幸的是,它们的长度不一样。
nicorellius 2012年

您可以尝试split使大文件更易于使用。
iglvzx 2012年

1
好。对大文件的任何处理都将花费时间,因此下面的答案将对此有所帮助。如果您只想提取想要的部分,并且可以大致估计出它的位置,则可以dd用来获取所需的位。例如dd if=bigfile of=extractfile bs=1M skip=10240 count=5将从10GB的点开始从文件中提取5MB。
保罗

Answers:



4

用一个具有单个字段的表创建一个MySQL数据库。然后将文件导入数据库。这将使查找特定行变得非常容易。

我不认为任何东西可以更快(如果headtail已失败)。最后,要查找行的应用程序必须n遍历整个文件,直到找到n换行为止。如果不进行某种查找(将行索引移至文件中的字节偏移),则无法获得更好的性能。

鉴于创建MySQL数据库并将数据导入其中非常容易,我觉得这是一种可行的方法。

这是操作方法:

DROP DATABASE IF EXISTS helperDb;
CREATE DATABASE `helperDb`;
CREATE TABLE `helperDb`.`helperTable`( `lineIndex` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `lineContent` MEDIUMTEXT , PRIMARY KEY (`lineIndex`) );
LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable (lineContent);
SELECT lineContent FROM helperTable WHERE ( lineIndex > 45000000 AND lineIndex < 45000100 );

/tmp/my_large_file 将是您要读取的文件。

导入在每行上具有制表符分隔值的文件的正确语法是:

LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable FIELDS TERMINATED BY '\n' (lineContent);

这样做的另一个主要优点是,如果您以后决定提取另一组行,则不必等待数小时即可再次进行处理(当然,除非您删除数据库)。


因此,这确实是一个很好的解决方案。我将其与以下sed命令一起使用,并确定了我的行。但是现在我有一个后续问题,即数据库方法可能更适合。我现在需要从文件中删除几百行。
nicorellius 2012年

我相信sed也可以做到。当然,如果您的数据库中有数据,则只用所需的行来导出新文件将是微不足道的。
Der Hochstapler,2012年

再次感谢。我sed回答了这个问题(因为它给了我更多直接的乐趣;-),但是给了你一个赞成票,因为以后我会用你的方法。我很感激。
nicorellius 2012年

1
您可以尝试将a添加FIELDS TERMINATED BY '\n'到该LOAD DATA行。
Der Hochstapler '02

1
抱歉,我的代码有误。我还为您的案例添加了正确的语法(这次进行了测试)。
Der Hochstapler,2012年

1

join和大文件的两个很好的旧工具split。您可以使用split with --lines=<number>选项将文件剪切为一定大小的多个文件。

例如split --lines=45000000 huge_file.txt。生成的零件将在xa,xb等中。然后,您可以head在零件xb中包含所需的行。您还可以将文件“联接”回单个大文件。


太好了,谢谢,我完全忘记了split命令。
Siliconrockstar

0

您拥有正确的工具,但使用不正确。正如之前在U&L 回答的那样tail -n +X file | head -n Y(请注意+)比sed从X开始的Y行要快10-15%。而且,方便的是,您不必exit像那样显式地进行该过程sed

tail将读取并丢弃前X-1行(没有办法解决),然后读取并打印以下行。头将读取并打印请求的行数,然后退出。当头退出时,尾部接收到SIGPIPE信号并死亡,因此它从输入文件中读取的缓冲区大小(通常为几千字节)的行数不会超过。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.