2017-05-05 61 views
2

我需要处理几个非常大的文件(每个大于90GB)。只有一小部分文件对我很重要。我想扫描文件并将必要的行写入另一个文件,所以我不需要每次运行实验时都处理这些大文件。每行大约有1000个字符。python - 处理非常大的文件(> 90GB)

我使用下面的代码:

def readFile(inputFile, outputFile): 
    startDate = datetime.datetime.strptime('10/06/2010 00:00:00', '%m/%d/%Y %H:%M:%S') 
    endDate = datetime.datetime.strptime('10/13/2010 23:59:59', '%m/%d/%Y %H:%M:%S') 

    total_lines = 0 

    with open(inputFile, 'r') as a_file: 
     for a_line in a_file: 

      total_lines += 1 

      id, date, content = splitLine(a_line) 

      datetime_object = datetime.datetime.strptime(date, '%m/%d/%Y %H:%M:%S') 

      if (datetime_object > startDate and datetime_object < endDate): 
       appendToFile(outputFile, a_line) 

    return total_lines 

def splitLine(long_string): 
    values = long_string.split(",") 
    return values[0],values[1],values[2] 

def appendToFile(outputFile, outputString): 
    try: 
     file = open(outputFile, 'a+') 
     file.write(outputString) 
     file.close() 
    except Exception as ex: 
     print("Error writing to file: " + outputFile) 
    return 

的问题是,我每次运行该脚本时,该过程被卡住各地10.000.000th线。当我使用htop命令时,我可以看到Python在卡住时仅使用大约8GB的RAM,并且使用的虚拟内存不断增加,然后OS在一段时间后终止该进程。

我使用了不同的文件,以及Python 2.7和3.5。我也尝试使用with open(inputFile, 'r', 16777216)来使用缓冲,但结果没有改变。我在macOS Sierra 10.12.4上运行代码,机器有16GB的RAM。

任何想法?

+0

'appendToFile()'做了什么?你应该包括一个完整的例子,其中包括*所有代码需要重现问题(“[mcve]”)。 – Carpetsmoker

+0

不要在评论中发布你的代码,你可以[编辑]你的问题;-) – Carpetsmoker

+0

@Carpetsmoker编辑:) – gokhan

回答

0

打开文件,直到找到你想要的东西。像这样:

f = open('yourfile') 

piece = f.read(4096) 
while piece: 
    # Implementation for each piece 
    piece = f.read(4096) 
f.close() 
0

更有效的方法是从python调用Unix awk命令。这将适用于Mac和Unix。

你打电话叫蟒蛇Unix命令是这样的:

import os 
os.popen('ls -l > result.txt') 

运行此示例代码将创建一个名为的Result.txt文件,其中包含ls -l命令的输出。

同样,您可以使用awk扫描您的文件并将结果传输到另一个文件。

从AWK的手册页:

AWK

NAME AWK - 图案定向扫描和处理语言

概要

awk [ -F fs ] [ -v var=value ] [ 'prog' | -f progfile ] [ file ... ] 

说明:

Awk扫描每个输入文件的行,这些行与在prog中或在指定为-f progfile的一个或多个文件中指定的任何一组模式匹配。对于每个模式,可以有一个相关的动作,当一行文件与该模式匹配时将执行相关的动作。每行匹配 针对每个模式动作语句的模式部分;针对每个匹配的模式执行相关联的动作。文件名称 - 表示标准输入。任何形式为var = value的文件都被视为一个赋值,而不是文件名,并且如果它是一个文件名,它将在它打开的时候被执行。选项-v后跟var = value是在执行prog之前完成的任务;任何数量的-v选项都可能存在。 -F fs选项将输入字段分隔符定义为正则表达式fs。

阅读此答案https://unix.stackexchange.com/questions/76805/read-log-file-between-two-dates了解如何使用awk在两个日期之间读取日志文件。