Как искать и заменять текст в файле?

Как мне искать и заменять текст в файле, используя Python 3?

Вот мой код:

import os
import sys
import fileinput

print ("Text to search for:")
textToSearch = input( "> " )

print ("Text to replace it with:")
textToReplace = input( "> " )

print ("File to perform Search-Replace on:")
fileToSearch  = input( "> " )
#fileToSearch = 'D:\dummy1.txt'

tempFile = open( fileToSearch, 'r+' )

for line in fileinput.input( fileToSearch ):
    if textToSearch in line :
        print('Match Found')
    else:
        print('Match Not Found!!')
    tempFile.write( line.replace( textToSearch, textToReplace ) )
tempFile.close()


input( '\n\n Press Enter to exit...' )

Входной файл:

hi this is abcd hi this is abcd
This is dummy text file.
This is how search and replace works abcd

Когда я ищу и заменяю 'ram' на 'abcd' в указанном выше входном файле, это работает как шарм. Но когда я делаю это наоборот, то есть заменяю abcd на ram, некоторые ненужные символы остаются в конце.

Замена abcd на ram

hi this is ram hi this is ram
This is dummy text file.
This is how search and replace works rambcd

Ответ 1

fileinput уже поддерживает редактирование на месте. В этом случае он перенаправляет stdout в файл:

#!/usr/bin/env python3
import fileinput

with fileinput.FileInput(filename, inplace=True, backup='.bak') as file:
    for line in file:
        print(line.replace(text_to_search, replacement_text), end='')

Ответ 2

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

# Read in the file
with open('file.txt', 'r') as file :
  filedata = file.read()

# Replace the target string
filedata = filedata.replace('ram', 'abcd')

# Write the file out again
with open('file.txt', 'w') as file:
  file.write(filedata)

Если у вас нет большого файла для работы, который слишком велик для загрузки в память за один раз, или вы обеспокоены потенциальной потерей данных, если процесс прервется во время второго шага, на котором вы записываете данные в файл.

Ответ 3

Как отметил Джек Айдли, и Дж. Ф. Себастьян указал, что этот код не будет работать:

 # Read in the file
filedata = None
with file = open('file.txt', 'r') :
  filedata = file.read()

# Replace the target string
filedata.replace('ram', 'abcd')

# Write the file out again
with file = open('file.txt', 'w') :
  file.write(filedata)`

Но этот код будет работать (я его протестировал):

f = open(filein,'r')
filedata = f.read()
f.close()

newdata = filedata.replace("old data","new data")

f = open(fileout,'w')
f.write(newdata)
f.close()

Используя этот метод, filein и fileout могут быть одним и тем же файлом, потому что Python 3.3 перезапишет файл при открытии для записи.

Ответ 4

Вы можете сделать замену следующим образом

f1 = open('file1.txt', 'r')
f2 = open('file2.txt', 'w')
for line in f1:
    f2.write(line.replace('old_text', 'new_text'))
f1.close()
f2.close()

Ответ 5

Ваша проблема связана с чтением и записью в тот же файл. Вместо того, чтобы открывать fileToSearch для записи, откройте фактический временный файл, а затем, после того как вы закончите и закроете tempFile, используйте os.rename, чтобы переместить новый файл поверх fileToSearch.

Ответ 6

Вы также можете использовать pathlib.

from pathlib2 import Path
path = Path(file_to_search)
text = path.read_text()
text = text.replace(text_to_search, replacement_text)
path.write_text(text)

Ответ 7

Мой вариант, по одному слову за весь файл.

Я прочитал его в памяти.

def replace_word(infile,old_word,new_word):
    if not os.path.isfile(infile):
        print ("Error on replace_word, not a regular file: "+infile)
        sys.exit(1)

    f1=open(infile,'r').read()
    f2=open(infile,'w')
    m=f1.replace(old_word,new_word)
    f2.write(m)

Ответ 8

Я сделал это:

#!/usr/bin/env python3

import fileinput
import os

Dir = input ("Source directory: ")
os.chdir(Dir)

Filelist = os.listdir()
print('File list: ',Filelist)

NomeFile = input ("Insert file name: ")

CarOr = input ("Text to search: ")

CarNew = input ("New text: ")

with fileinput.FileInput(NomeFile, inplace=True, backup='.bak') as file:
    for line in file:
        print(line.replace(CarOr, CarNew), end='')

file.close ()

Ответ 9

def word_replace(filename,old,new):
    c=0
    with open(filename,'r+',encoding ='utf-8') as f:
        a=f.read()
        b=a.split()
        for i in range(0,len(b)):
            if b[i]==old:
                c=c+1
        old=old.center(len(old)+2)
        new=new.center(len(new)+2)
        d=a.replace(old,new,c)
        f.truncate(0)
        f.seek(0)
        f.write(d)
    print('All words have been replaced!!!')

Ответ 10

(pip install python-util)

from pyutil import filereplace

filereplace("somefile.txt","abcd","ram")

Второй параметр (вещь, которую нужно заменить, например, "abcd" также может быть регулярным выражением)
Заменим все случаи

Ответ 12

Я слегка изменил пост Джейрая Сингха, чтобы заменить каждый экземпляр '!' символ к числу, которое я хотел бы увеличить с каждым экземпляром. Думал, что это может быть полезно для тех, кто хотел изменить персонаж, который произошел более одного раза в строке и хотел итерации. Надежда помогает кому-то. PS - Я очень новичок в кодировании, так что извиняюсь, если мой пост неуместен, но это сработало для меня.

f1 = open('file1.txt', 'r')
f2 = open('file2.txt', 'w')
n = 1  

# if word=='!'replace w/ [n] & increment n; else append same word to     
# file2

for line in f1:
    for word in line:
        if word == '!':
            f2.write(word.replace('!', f'[{n}]'))
            n += 1
        else:
            f2.write(word)
f1.close()
f2.close()

Ответ 13

С одним блоком, вы можете найти и заменить свой текст:

with open('file.txt','r+') as f:
    filedata = f.read()
    filedata = filedata.replace('abc','xyz')
    f.truncate(0)
    f.write(filedata)

Ответ 14

def findReplace (найти, заменить):

import os 

src = os.path.join(os.getcwd(), os.pardir) **'//To get the folder in which files are present'** 

for path, dirs, files in os.walk(os.path.abspath(src)):

    for name in files: 

        if name.endswith('.py'): 

            filepath = os.path.join(path, name)

            with open(filepath) as f: 

                s = f.read() 

            s = s.replace(find, replace) 

            with open(filepath, "w") as f:

                f.write(s)