Как найти и заменить строку в Python с большим набором данных - PullRequest
3 голосов
/ 12 октября 2019

Я пытаюсь изменить разделитель большого файла размером около 4 ГБ. В настоящее время разделителем является "# | #", и я хочу, чтобы он был "|".

Я попытался выполнить замену и найти, но из-за большого файла на моем компьютере недостаточно памяти для завершениякод. Мне было интересно, есть ли способ читать файлы построчно, чтобы сэкономить память.

text = open("C:\\test.txt", "r")
text = ''.join([i for i in text]).replace("#|#", "|")
x = open("C:\\test.txt","w")
x.writelines(text)
x.close()

Вот как файл выглядит в настоящее время:

FIELD # | # FIELD # | # FIELD # | #

и я хочу, чтобы он выглядел

ПОЛЕ |ПОЛЕ |ПОЛЕ |

Ответы [ 2 ]

3 голосов
/ 12 октября 2019

Конечно, вы можете писать построчно. На самом деле, обработка файлов более практична в более идиоматическом способе использования файлового объекта в качестве диспетчера контекста и итератора строк:

import shutil

with open("C:\\test.txt", "r") as long_file, \
     open("C:\\test_replaced.tmp", "w") as replacement:
    for line in long_file:
        replacement.write(line.replace("#|#", "|"))

shutil.move("C:\\test_replaced.tmp", "C:\\test.txt")

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

1 голос
/ 12 октября 2019

Попробуйте использовать генератор вместо чтения всего файла в память:

text = open("C:\\test.txt", "r")
text = ''.join((i for i in text)).replace("#|#", "|")
x = open("C:\\test.txt","w")
x.writelines(text)
x.close()

(i for i in text) синтаксис позволяет лениво генерировать строки в отличие от [i for i in text] при загрузке всехстроки в память

...