Как разбить огромный текстовый файл на python

У меня огромный текстовый файл (~ 1 ГБ), и, к сожалению, текстовый редактор, который я использую, не будет читать такой большой файл. Однако, если я могу просто разбить его на две или три части, я буду в порядке, поэтому, как упражнение, я хотел написать программу на python, чтобы сделать это.

То, что я думаю, что я хочу, чтобы программа выполняла, – это найти размер файла, разделить это число на части, и для каждой части читать до этой точки в кусках, записывать в файл .nnn файла filename, к следующему разрыву строки и напишите это, затем закройте выходной файл и т. д. Очевидно, что последний выходной файл просто копирует в конец входного файла.

Можете ли вы мне помочь с ключевыми файлами, связанными с файлами: файлы, чтение и запись в кусках и чтение в режиме разрыва строки?

Сначала я буду писать этот тест кода, поэтому нет необходимости давать мне полный ответ, если только его однострочный 😉

13 Solutions collect form web for “Как разбить огромный текстовый файл на python”

Проверьте os.stat() для размера файла и файла file.readlines([sizehint]) . Эти две функции должны быть все, что вам нужно для чтения, и, надеюсь, вы знаете, как писать:

linux имеет команду разделения

split -l 100000 file.txt

будет разделяться на файлы размером 100 000 строк

В качестве альтернативного метода, используя библиотеку регистрации:

 >>> import logging.handlers >>> log = logging.getLogger() >>> fh = logging.handlers.RotatingFileHandler("D://filename.txt", maxBytes=2**20*100, backupCount=100) # 100 MB each, up to a maximum of 100 files >>> log.addHandler(fh) >>> log.setLevel(logging.INFO) >>> f = open("D://biglog.txt") >>> while True: ... log.info(f.readline().strip()) 

Ваши файлы будут выглядеть следующим образом:

filename.txt (конец файла)
filename.txt.1
filename.txt.2

filename.txt.10 (начало файла)

Это быстрый и простой способ сделать огромный файл журнала RotatingFileHandler реализацией RotatingFileHandler .

не забывайте искать () и mmap () для произвольного доступа к файлам.

 def getSomeChunk(filename, start, len): fobj = open(filename, 'r+b') m = mmap.mmap(fobj.fileno(), 0) return m[start:start+len] 

Этот метод генератора (медленный) способ получить кусочек строк без раздувания вашей памяти.

 import itertools def slicefile(filename, start, end): lines = open(filename) return itertools.islice(lines, start, end) out = open("/blah.txt", "w") for line in slicefile("/python27/readme.txt", 10, 15): out.write(line) 

Вы можете использовать wc и split (см. Соответствующие manpages), чтобы получить желаемый эффект. В bash :

 split -dl$((`wc -l 'filename'|sed 's/ .*$//'` / 3 + 1)) filename filename-chunk. 

производит 3 части одного и того же linecount (с ошибкой округления в последнем, конечно), именовал filename-chunk.00 в filename-chunk.02 .

Я написал программу, и она работает нормально. Так спасибо Камилю Кисиэлю за то, что вы меня начали.
(Обратите внимание, что FileSizeParts () – это функция, не показанная здесь)
Позже я могу обойтись, чтобы сделать версию, которая делает бинарное чтение, чтобы увидеть, если он быстрее.

 def Split(inputFile,numParts,outputName): fileSize=os.stat(inputFile).st_size parts=FileSizeParts(fileSize,numParts) openInputFile = open(inputFile, 'r') outPart=1 for part in parts: if openInputFile.tell()<fileSize: fullOutputName=outputName+os.extsep+str(outPart) outPart+=1 openOutputFile=open(fullOutputName,'w') openOutputFile.writelines(openInputFile.readlines(part)) openOutputFile.close() openInputFile.close() return outPart-1 

Хотя ответ Райана Гинстрома верен, на это требуется больше времени (как он уже отмечал). Вот способ обойти многочисленные вызовы itertools.islice , последовательно повторяя дескриптор открытого файла:

 def splitfile(infilepath, chunksize): fname, ext = infilepath.rsplit('.',1) i = 0 written = False with open(infilepath) as infile: while True: outfilepath = "{}{}.{}".format(fname, i, ext) with open(outfilepath, 'w') as outfile: for line in (infile.readline() for _ in range(chunksize)): outfile.write(line) written = bool(line) if not written: break i += 1 

Это сработало для меня

 import os fil = "inputfile" outfil = "outputfile" f = open(fil,'r') numbits = 1000000000 for i in range(0,os.stat(fil).st_size/numbits+1): o = open(outfil+str(i),'w') segment = f.readlines(numbits) for c in range(0,len(segment)): o.write(segment[c]+"\n") o.close() 

использование – split.py имя файла splitsizeinkb

 import os import sys def getfilesize(filename): with open(filename,"rb") as fr: fr.seek(0,2) # move to end of the file size=fr.tell() print("getfilesize: size: %s" % size) return fr.tell() def splitfile(filename, splitsize): # Open original file in read only mode if not os.path.isfile(filename): print("No such file as: \"%s\"" % filename) return filesize=getfilesize(filename) with open(filename,"rb") as fr: counter=1 orginalfilename = filename.split(".") readlimit = 5000 #read 5kb at a time n_splits = filesize//splitsize print("splitfile: No of splits required: %s" % str(n_splits)) for i in range(n_splits+1): chunks_count = int(splitsize)//int(readlimit) data_5kb = fr.read(readlimit) # read # Create split files print("chunks_count: %d" % chunks_count) with open(orginalfilename[0]+"_{id}.".format(id=str(counter))+orginalfilename[1],"ab") as fw: fw.seek(0) fw.truncate()# truncate original if present while data_5kb: fw.write(data_5kb) if chunks_count: chunks_count-=1 data_5kb = fr.read(readlimit) else: break counter+=1 if __name__ == "__main__": if len(sys.argv) < 3: print("Filename or splitsize not provided: Usage: filesplit.py filename splitsizeinkb ") else: filesize = int(sys.argv[2]) * 1000 #make into kb filename = sys.argv[1] splitfile(filename, filesize) 

Или python-версия wc и split:

 lines = 0 for l in open(filename): lines += 1 

Затем некоторый код для чтения первых строк / 3 в один файл, следующих строк / 3 в другой и т. Д.

У меня было требование разделить файлы csv для импорта в Dynamics CRM, так как ограничение размера файла для импорта составляет 8 МБ, а файлы, которые мы получаем, намного больше. Эта программа позволяет пользователю вводить имена файлов и LinesPerFile, а затем разбивать указанные файлы на запрошенное количество строк. Я не могу поверить, как быстро это работает!

 # user input FileNames and LinesPerFile FileCount = 1 FileNames = [] while True: FileName = raw_input('File Name ' + str(FileCount) + ' (enter "Done" after last File):') FileCount = FileCount + 1 if FileName == 'Done': break else: FileNames.append(FileName) LinesPerFile = raw_input('Lines Per File:') LinesPerFile = int(LinesPerFile) for FileName in FileNames: File = open(FileName) # get Header row for Line in File: Header = Line break FileCount = 0 Linecount = 1 for Line in File: #skip Header in File if Line == Header: continue #create NewFile with Header every [LinesPerFile] Lines if Linecount % LinesPerFile == 1: FileCount = FileCount + 1 NewFileName = FileName[:FileName.find('.')] + '-Part' + str(FileCount) + FileName[FileName.find('.'):] NewFile = open(NewFileName,'w') NewFile.write(Header) NewFile.write(Line) Linecount = Linecount + 1 NewFile.close() 

Вот скрипт python, который вы можете использовать для разделения больших файлов с помощью subprocess :

 """ Splits the file into the same directory and deletes the original file """ import subprocess import sys import os SPLIT_FILE_CHUNK_SIZE = '5000' SPLIT_PREFIX_LENGTH = '2' # subprocess expects a string, ie 2 = aa, ab, ac etc.. if __name__ == "__main__": file_path = sys.argv[1] # ie split -a 2 -l 5000 t/some_file.txt ~/tmp/t/ subprocess.call(["split", "-a", SPLIT_PREFIX_LENGTH, "-l", SPLIT_FILE_CHUNK_SIZE, file_path, os.path.dirname(file_path) + '/']) # Remove the original file once done splitting try: os.remove(file_path) except OSError: pass 

Вы можете вызвать его извне:

 import os fs_result = os.system("python file_splitter.py {}".format(local_file_path)) 

Вы также можете импортировать subprocess и запустить его непосредственно в своей программе.

Проблема с этим подходом заключается в использовании большой памяти: subprocess создает вилку с размером памяти, размером с ваш процесс, и если ваша память процесса уже тяжелая, она удваивает ее на время ее запуска. То же самое с os.system .

Вот еще один чистый способ python сделать это, хотя я не тестировал его на огромных файлах, он будет медленнее, но будет более компактным по памяти:

 CHUNK_SIZE = 5000 def yield_csv_rows(reader, chunk_size): """ Opens file to ingest, reads each line to return list of rows Expects the header is already removed Replacement for ingest_csv :param reader: dictReader :param chunk_size: int, chunk size """ chunk = [] for i, row in enumerate(reader): if i % chunk_size == 0 and i > 0: yield chunk del chunk[:] chunk.append(row) yield chunk with open(local_file_path, 'rb') as f: f.readline().strip().replace('"', '') reader = unicodecsv.DictReader(f, fieldnames=header.split(','), delimiter=',', quotechar='"') chunks = files.yield_csv_rows(reader, CHUNK_SIZE) for chunk in chunks: if not chunk: break # Do something with your chunk here 
  • Переписывая текстовый файл для оценки, чтобы убедиться, что он имеет только последние 4 балла (python)
  • Как выполнить бинарный поиск в текстовом файле для поиска ключевого слова в python?
  • Как вернуть уникальные слова из текстового файла с помощью Python
  •  
    Interesting Posts for Van-Lav

    TypeError: может присоединяться только к iterable python

    Изменить значение текущего итерированного элемента в списке

    UnicodeDecodeError: кодек ascii не может декодировать байт 0xe0 в позиции 0: порядковый номер не в диапазоне (128)

    API сайтов Google + OAuth2 (на Appengine)

    Как генерировать случайные цвета в matplotlib?

    Как выполнить экспоненциальную и логарифмическую подгонку кривой в Python? Я нашел только полиномиальную подгонку

    python – проверить в конце цикла, если нужно снова запустить

    AppEngine: хранилище данных запроса для записей с <отсутствующим> значением

    Отображение значения словаря в списке

    как распечатать выходные данные на странице html с помощью python?

    Бесконечно вложенный словарь в Python

    Python Matplotlib: динамически обновлять график – длина массива неизвестна априори

    Программа силового оператора в C

    Работа не работает должным образом в Tensorflow

    Как использовать переменные в регулярном выражении Python

    Python - лучший язык программирования в мире.