我现在有一个非常简单的脚本,它使用enumerate()
:计算文本文件中的行数
i = 0
f = open("C:/Users/guest/Desktop/file.log", "r")
for i, line in enumerate(f):
pass
print i + 1
f.close()
这大约需要3分钟半的时间来浏览一个15GB的日志文件,其中大约有3000万行。如果我能在两分钟或更短的时间内完成这项工作,那就太好了,因为这些都是每日日志,我们想每月进行一次分析,所以代码必须处理30个15GB的日志,可能超过一个半小时,我们希望尽量减少时间;服务器上的内存负载。
我也会选择一个好的近似/估计方法,但它需要大约4西格的准确度。。。
谢谢!
Ignacio的答案是正确的,但如果您有一个32位的进程,则可能会失败。
但是,按块读取文件,然后计算每个块中的n
字符可能会很有用。
def blocks(files, size=65536):
while True:
b = files.read(size)
if not b: break
yield b
with open("file", "r") as f:
print sum(bl.count("n") for bl in blocks(f))
会做好你的工作。
请注意,我没有以二进制文件的形式打开该文件,因此rn
将转换为n
,从而使计数更加可靠。
对于Python3,为了使其更加健壮,用于读取具有各种字符的文件:
def blocks(files, size=65536):
while True:
b = files.read(size)
if not b: break
yield b
with open("file", "r",encoding="utf-8",errors='ignore') as f:
print (sum(bl.count("n") for bl in blocks(f)))
我知道这有点不公平,但你可以这样做
int(subprocess.check_output("wc -l C:\alarm.bat").split()[0])
如果您使用的是Windows,请查看Coreutils。
一个快速的单线解决方案是:
sum(1 for i in open(file_path, 'rb'))
它应该适用于任意大小的文件。
mmap文件,并计算换行数。
import mmap
def mapcount(filename):
with open(filename, "r+") as f:
buf = mmap.mmap(f.fileno(), 0)
lines = 0
readline = buf.readline
while readline():
lines += 1
return lines
我会扩展gl的答案,并使用多处理Python模块运行他/她的代码以加快计数:
def blocks(f, cut, size=64*1024): # 65536
start, chunk =cut
iter=0
read_size=int(size)
_break =False
while not _break:
if _break: break
if f.tell()+size>start+chunk:
read_size=int(start+chunk- f.tell() )
_break=True
b = f.read(read_size)
iter +=1
if not b: break
yield b
def get_chunk_line_count(data):
fn, chunk_id, cut = data
start, chunk =cut
cnt =0
last_bl=None
with open(fn, "r") as f:
if 0:
f.seek(start)
bl = f.read(chunk)
cnt= bl.count('n')
else:
f.seek(start)
for i, bl in enumerate(blocks(f,cut)):
cnt += bl.count('n')
last_bl=bl
if not last_bl.endswith('n'):
cnt -=1
return cnt
....
pool = multiprocessing.Pool(processes=pool_size,
initializer=start_process,
)
pool_outputs = pool.map(get_chunk_line_count, inputs)
pool.close() # no more tasks
pool.join()
这将使计数性能提高20倍。我把它包装成一个脚本,然后放到Github上。