Jak wyszukiwać i zamieniać tekst w pliku za pomocą Python 3?
Oto mój kod:
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...' )
Plik wejściowy:
hi this is abcd hi this is abcd
This is dummy text file.
This is how search and replace works abcd
Kiedy szukam i zastępuję „ram” przez „abcd” w powyższym pliku wejściowym, działa to jako urok. Ale kiedy robię to na odwrót, tj. Zastępując „abcd” przez „ram”, niektóre śmieciowe postacie pozostają na końcu.
Zamiana „abcd” na „ram”
hi this is ram hi this is ram
This is dummy text file.
This is how search and replace works rambcd
Odpowiedzi:
fileinput
już obsługuje edycję w miejscu. Wstdout
tym przypadku przekierowuje do pliku:źródło
end=''
powinien zrobić argument?line
ma już nową linię.end
jest domyślnie nową linią,end=''
sprawia , żeprint()
funkcja nie drukuje dodatkowej nowej liniifileinput
nie jest narzędziem do wszystkich zadań ( nic nie jest), ale w wielu przypadkach jest to właściwe narzędzie, np. do implementacjised
podobnego filtra w Pythonie. Nie używaj śrubokręta do wbijania gwoździ.fileinput
(w zasadzie użyjtry..finally
lub menedżer kontekstu, aby upewnić się, że później przywrócisz standardowe wyjście stdout). Kod źródłowyfileinput
jest dość okropnie okropny i robi kilka naprawdę niebezpiecznych rzeczy pod maską. Gdybym został napisany dzisiaj, bardzo wątpię, aby znalazł się w stdlib.Jak wskazał michaelb958, nie można zastąpić danych o innej długości, ponieważ spowoduje to usunięcie pozostałych części. Nie zgadzam się z innymi plakatami sugerującymi czytanie z jednego pliku i pisanie do innego. Zamiast tego wczytywałbym plik do pamięci, naprawił dane, a następnie zapisałbym go w tym samym pliku w osobnym kroku.
Chyba że masz ogromny plik do pracy, który jest zbyt duży, aby załadować go do pamięci za jednym razem, lub martwisz się potencjalną utratą danych, jeśli proces zostanie przerwany podczas drugiego etapu, w którym zapisujesz dane do pliku.
źródło
with file = open(..):
nie jest prawidłową funkcją Python (=
), chociaż zamiar jest jasny..replace()
nie modyfikuje ciągu (jest niezmienny), więc musisz użyć zwróconej wartości. W każdym razie kod obsługujący duże pliki może być jeszcze prostszy, chyba że musisz wyszukać i zamienić tekst obejmujący wiele wierszy.with
Oświadczenie automatycznie zamyka plik na końcu bloku instrukcji.Jak napisał Jack Aidley i JF Sebastian, ten kod nie będzie działał:
Ale ten kod BĘDZIE działał (przetestowałem go):
Dzięki tej metodzie filein i fileout mogą być tym samym plikiem, ponieważ Python 3.3 nadpisze plik po otwarciu do zapisu.
źródło
with
-statement? 2. Jak stwierdzono w mojej odpowiedzi,fileinput
może działać w miejscu - może zastępować dane w tym samym pliku (używa pliku tymczasowego wewnętrznie). Różnica polega na tym,fileinput
że nie wymaga ładowania całego pliku do pamięci.with
bloków).Możesz dokonać takiej wymiany
źródło
Możesz także użyć
pathlib
.źródło
Za pomocą pojedynczego z blokiem możesz wyszukiwać i zamieniać tekst:
źródło
seek
na początku pliku przed jego zapisaniem.truncate
nie robi tego, więc będziesz mieć śmieci w pliku.Twój problem wynika z odczytu i zapisu do tego samego pliku. Zamiast otwierać
fileToSearch
do pisania, otwórz rzeczywisty plik tymczasowy, a następnie po zakończeniu i zamknięciutempFile
użyj,os.rename
aby przenieść nowy plikfileToSearch
.źródło
(pip install python-util)
Drugi parametr (rzecz do zastąpienia, np. „Abcd” może być również wyrażeniem regularnym)
Zastąpi wszystkie wystąpienia
źródło
Mój wariant, jedno słowo na raz w całym pliku.
Przeczytałem to w pamięci.
źródło
Ja to zrobiłem:
źródło
fileinput
nie współpracujęinplace=True
zutf-8
.Lekko zmodyfikowałem post Jayram Singha, aby zastąpić każde wystąpienie „!” znak do liczby, którą chciałem zwiększać z każdą instancją. Pomyślałem, że może to być pomocne dla kogoś, kto chciał zmodyfikować znak, który pojawiał się więcej niż raz w linii i chciał iterować. Mam nadzieję, że komuś pomoże. PS - Jestem bardzo nowy w kodowaniu, więc przepraszam, jeśli mój post jest w jakikolwiek sposób nieodpowiedni, ale to zadziałało dla mnie.
źródło
źródło
Tak jak:
źródło
źródło