我需要处理几个非常大的文件(每个> 90GB)。只有一小部分文件对我很重要。我想扫描文件并将必要的行写入另一个文件,因此每次运行实验时我都不需要处理这么大的文件。每行约1000个字符。
我使用以下代码:
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.000行左右。当我使用htop
命令时,我可以看到Python在卡住时仅使用大约8GB的RAM,并且使用的虚拟内存不断增加,然后操作系统会在一段时间后终止该进程。
我使用了不同的文件,也使用了Python 2.7和3.5。我也尝试使用with open(inputFile, 'r', 16777216)
来使用缓冲,但结果没有改变。我在macOS Sierra 10.12.4上运行代码,机器有16GB的RAM。
有什么想法吗?
答案 0 :(得分:0)
分段打开文件,直到找到所需内容。像这样:
f = open('yourfile')
piece = f.read(4096)
while piece:
# Implementation for each piece
piece = f.read(4096)
f.close()
答案 1 :(得分:0)
更有效的方法是从python调用Unix awk命令。这适用于Mac和unix。
你可以像这样从python调用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在两个日期之间读取日志文件。