【发布时间】:2015-09-07 02:46:06
【问题描述】:
我尝试过类似的方法
file_in <- file("myfile.log","r")
x <- readLines(file_in, n=-100)
但我还在等……
任何帮助将不胜感激
【问题讨论】:
-
可以想象你必须等待很长时间。负 n 值表示读取到文件末尾。如果该文件是 7.5 Gb,那么...
我尝试过类似的方法
file_in <- file("myfile.log","r")
x <- readLines(file_in, n=-100)
但我还在等……
任何帮助将不胜感激
【问题讨论】:
我会使用scan,以防你知道日志有多少行:
scan("foo.txt",sep="\n",what="char(0)",skip=100)
如果你不知道你需要跳过多少,你别无选择,只能朝着其中一个方向前进
scan("foo.txt",sep="\n",what=list(NULL)) 找出有多少条记录,或者最后一个选项可能如下所示:
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)
如果你知道你有超过 1000 万行。当您开始拥有非常大的日志时,这可以节省阅读时间。
编辑:事实上,考虑到文件的大小,我什至不会为此使用 R。在 Unix 上,您可以使用 tail 命令。在工具包中的某个地方也有一个 Windows 版本。不过我还没试过。
【讨论】:
wc)可能会更容易/更快。其他:我不明白while(1) {...} 的意思。这个循环会结束吗?
break 部分,不知何故我忽略了它:) 抱歉打扰了。
tail的windows版本吗?
while(TRUE) 会更容易理解 - 不依赖于内部强制逻辑。
您可以通过指定skip 参数来使用read.table 执行此操作。如果您的行不被解析为变量,请将分隔符指定为'\n',正如下面@Joris Meys 指出的那样,并设置as.is=TRUE 以获取字符向量而不是因子。
小例子(跳过前 2000 行):
df <- read.table('foo.txt', sep='\n', as.is=TRUE, skip=2000)
【讨论】:
read.table("foo.txt",sep="\n",as.is=T,skip=100)
wc 可以在几秒钟内解析文件。如果使用 Linux,您还可以从 R 调用 wc(请参阅:?system)。
tail 命令:computerhope.com/unix/utail.htm
您可以通过以下方法读取最后n行
第 1 步 - 根据需要打开文件
df <- read.csv("hw1_data.csv")
第 2 步 - 现在使用 tail 函数从最后读取 n 行
tail(df, 2)
【讨论】:
正如@JorisMeys 已经提到的,unix 命令tail 将是解决此问题的最简单方法。但是我想提出一个基于seek 的R 解决方案,从文件末尾开始读取文件:
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)
【讨论】:
有些人已经说过了,但是如果你有一个很大的日志,最好只读入你需要的东西,而不是把它全部读入内存,然后对你需要的东西进行子集化。
为此,我们使用 R 的 system() 来运行 Linux tail 命令。
system("tail path/to/my_file.log")
system("tail -n 2 path/to/my_file.log")
last_2_lines <- system("tail -n 2 path/to/my_file.log", intern = TRUE)
【讨论】:
查看最后几行:
tail(file_in,100)
【讨论】: