我在查看非常大的文本文件块时遇到了问题。这个文件大约有 19 GB,显然太大了,无法通过任何传统方式查看。
head 1
我尝试过tail 1
将两个命令以各种方式连接在一起(以得到中间的部分),但没有成功。我的 Linux 机器运行的是 Ubuntu 9.10,无法处理此文件head -n 1
。tail -n 1
我该如何处理这个文件?我的最终目标是专注于第 45000000 行和第 45000100 行。
答案1
您应该使用sed
。
sed -n -e 45000000,45000100p -e 45000101q bigfile > savedlines
这告诉sed
打印第 45000000 行至第 45000100 行(含),并在第 45000101 行退出。
答案2
创建一个包含单个字段的单个表的 MySQL 数据库。然后将文件导入数据库。这样可以非常轻松地查找某一行。
我认为没有其他方法可以更快(如果head
已经tail
失败)。最后,想要查找行的应用程序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);
这样做的另一个主要优点是,如果您稍后决定提取另一组行,则不必再次等待数小时进行处理(当然,除非您删除数据库)。
答案3
两个处理大文件的好用的老工具是join
和split
。您可以使用 split--lines=<number>
选项将文件剪切为多个特定大小的文件。
例如split --lines=45000000 huge_file.txt
。结果部分将位于 xa、xb 等中。然后,您可以将head
部分討厭它将包含您想要的行。您还可以将文件“合并”回单个大文件。
答案4
你有正确的工具,但使用方式不正确。如前所述已回答在 U&L 上,tail -n +X file | head -n Y
(注意+
)比从 X 开始的 Y 线快 10-15% sed
。并且方便的是,您不必exit
像那样明确地执行该过程sed
。
tail 将读取并丢弃前 X-1 行(这是无法避免的),然后读取并打印以下行。head 将读取并打印请求的行数,然后退出。当 head 退出时,tail 会收到 SIGPIPE 信号并终止,因此它不会从输入文件中读取超过缓冲区大小(通常为几千字节)的行。