Como pesquiso e substituo o texto em um arquivo usando o Python 3?
Aqui está o meu código:
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...' )
Arquivo de entrada:
hi this is abcd hi this is abcd
This is dummy text file.
This is how search and replace works abcd
Quando eu procuro e substituo 'ram' por 'abcd' no arquivo de entrada acima, ele funciona como um encanto. Mas quando eu faço isso vice-versa, ou seja, substituindo 'abcd' por 'ram', alguns caracteres indesejados são deixados no final.
Substituindo 'abcd' por 'ram'
hi this is ram hi this is ram
This is dummy text file.
This is how search and replace works rambcd
Respostas:
fileinput
já suporta edição no local. Ele redirecionastdout
para o arquivo neste caso:fonte
end=''
argumento deveria fazer?line
já tem uma nova linha.end
é uma nova linha por padrão,end=''
faz com queprint()
a função não imprimem nova linha adicionalfileinput
não é uma ferramenta para todos os trabalhos ( nada é), mas há muitos casos em que é a ferramenta certa, por exemplo, para implementar umsed
filtro semelhante no Python. Não use uma chave de fenda para bater nas unhas.fileinput
faz (basicamente, usetry..finally
ou um gerenciador de contexto para garantir que você retorne o stdout ao seu valor original posteriormente). O código-fonte parafileinput
é bastante horrível, e faz algumas coisas realmente inseguras. Se ele fosse escrito hoje, duvido muito que ele fosse incluído no stdlib.Conforme apontado por michaelb958, você não pode substituir no lugar por dados de comprimento diferente, pois isso colocará o restante das seções fora do lugar. Discordo dos outros pôsteres que sugerem que você leia um arquivo e escreva para outro. Em vez disso, eu lia o arquivo na memória, corrigia os dados e os escrevia no mesmo arquivo em uma etapa separada.
A menos que você tenha um arquivo grande para trabalhar, grande demais para carregar na memória de uma só vez, ou esteja preocupado com a perda potencial de dados, se o processo for interrompido durante a segunda etapa na qual você grava dados no arquivo.
fonte
with file = open(..):
não é válido Python (=
), embora a intenção seja clara..replace()
não modifica a sequência (é imutável), portanto você precisa usar o valor retornado. De qualquer forma, o código que suporta arquivos grandes pode ser ainda mais simples, a menos que você precise pesquisar e substituir texto que se estende por várias linhas.with
instrução fecha automaticamente o arquivo no final do bloco de instruções.Como Jack Aidley postou e JF Sebastian apontou, este código não funcionará:
Mas esse código funcionará (eu testei):
Usando esse método, filein e fileout podem ser o mesmo arquivo, porque o Python 3.3 substituirá o arquivo na abertura para gravação.
fonte
with
-statement? 2. Como indicado na minha resposta,fileinput
pode funcionar no local - ele pode substituir os dados no mesmo arquivo (ele usa um arquivo temporário internamente). A diferença é quefileinput
não é necessário carregar o arquivo inteiro na memória.with
blocos).Você pode fazer a substituição assim
fonte
Você também pode usar
pathlib
.fonte
Com um único bloco, você pode pesquisar e substituir seu texto:
fonte
seek
o início do arquivo antes de escrevê-lo.truncate
não faz isso e, portanto, você terá lixo no arquivo.Seu problema decorre da leitura e gravação no mesmo arquivo. Em vez de abrir
fileToSearch
para escrever, abra um arquivo temporário real e, depois de terminar e fechartempFile
, useos.rename
para mover o novo arquivofileToSearch
.fonte
(instalação pip python-util)
O segundo parâmetro (o item a ser substituído, por exemplo, "abcd" também pode ser um regex)
substituirá todas as ocorrências
fonte
Minha variante, uma palavra de cada vez no arquivo inteiro.
Eu li na memória.
fonte
Eu fiz isso:
fonte
fileinput
não trabalhainplace=True
comutf-8
.Modifiquei levemente a postagem de Jayram Singh para substituir todas as instâncias de um '!' caractere para um número que eu queria incrementar com cada instância. Achei que poderia ser útil para alguém que quisesse modificar um personagem que ocorresse mais de uma vez por linha e quisesse iterar. Espero que ajude alguém. PS- Eu sou muito novo em codificação, então peço desculpas se minha postagem for inadequada de alguma forma, mas isso funcionou para mim.
fonte
fonte
Igual a:
fonte
fonte