从巨大的文本文件中读取最后n行

我试过这样的事情

file_in <- file("myfile.log","r") x <- readLines(file_in, n=-100) 

但我还在等

任何帮助将不胜感激

Solutions Collecting From Web of "从巨大的文本文件中读取最后n行"

我会使用scan ,以防万一你知道日志有多少行:

 scan("foo.txt",sep="\n",what="char(0)",skip=100) 

如果你不知道你需要跳过多少,你别无选择,只能走向任何一个

  • 阅读所有内容并记下最后n行(如果可行)
  • 使用scan("foo.txt",sep="\n",what=list(NULL))来计算出有多少条记录,或者
  • 使用一些算法来遍历文件,每次只保留最后n行

最后一个选项可能如下所示:

 ReadLastLines <- function(x,n,...){ con <- file(x) open(con) out <- scan(con,n,what="char(0)",sep="\n",quiet=TRUE,...) while(TRUE){ tmp <- scan(con,1,what="char(0)",sep="\n",quiet=TRUE) if(length(tmp)==0) {close(con) ; break } out <- c(out[-1],tmp) } out } 

允许:

 ReadLastLines("foo.txt",100) 

要么

 ReadLastLines("foo.txt",100,skip=1e+7) 

如果你知道你有超过一千万行。 这可以节省您的阅读时间,当你开始有非常大的日志。


编辑:其实,我甚至不使用R这个,给你的文件的大小。 在Unix上,您可以使用tail命令。 有一个Windows版本,以及在工具包中的某个地方。 尽管如此,我还没有尝试过。

你可以通过指定skip参数来实现read.table 如果你的行不能被解析为变量,就像@Joris Meys指出的那样,将分隔符指定为'\n' ,并且设置as.is=TRUE来获取字符向量而不是因子。

小例子(跳过头2000行):

 df <- read.table('foo.txt', sep='\n', as.is=TRUE, skip=2000) 

正如@JorisMeys已经提到的那样,unix命令tail是解决这个问题的最简单的方法。 不过,我想提出一个基于seekR解决方案,从文件末尾开始读取文件:

 tailfile <- function(file, n) { bufferSize <- 1024L size <- file.info(file)$size if (size < bufferSize) { bufferSize <- size } pos <- size - bufferSize text <- character() k <- 0L f <- file(file, "rb") on.exit(close(f)) while(TRUE) { seek(f, where=pos) chars <- readChar(f, nchars=bufferSize) k <- k + length(gregexpr(pattern="\\n", text=chars)[[1L]]) text <- paste0(text, chars) if (k > n || pos == 0L) { break } pos <- max(pos-bufferSize, 0L) } tail(strsplit(text, "\\n")[[1L]], n) } tailfile(file, n=100)