Python Forum

Full Version: Replace string in many files in a folder
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
This code changes a string in 1 text file in python
s = open("sample.txt").read()
s = s.replace('abcd', 'efgh')
f = open("mount.txt", 'w')
f.write(s)
f.close()
How do I change a single string ex: from abcd to efgh in 100's of text files under a single directory.

Thanks

I also tried this.It runs without errors but changes nothing in the text files.
I ran the code under the directory under which the files are stored.
import glob,os,fileinput
from glob import glob
for filename in glob('*.LIC'):
    with fileinput.FileInput(filename, inplace=True, backup='.bak') as file:
        for line in file:
            print(line.replace('abcd', 'efgh'),  end='')
It seems to me that the first argument of FileInput is a sequence of files. You could perhaps pass the tuple (filename,) instead of filename. Also you could perhaps do a single call with FileInput(glob('*LIC'), ...)
One can use os.scandir() to get list of files in current directory:

files = [entry for entry in os.scandir() if entry.name.endswith('.LIC')] 
Then iterate over this list to open files, read content, make replacement and write back (warning: this is untested code):

for file in files:
    with open(file, 'r+') as f:
        content = f.read().replace('abcd', 'efgh')
        f.write(content)
(Oct-14-2019, 07:39 AM)perfringo Wrote: [ -> ]One can use os.scandir() to get list of files in current directory:

files = [entry for entry in os.scandir() if entry.name.endswith('.LIC')] 
Then iterate over this list to open files, read content, make replacement and write back (warning: this is untested code):

for file in files:
    with open(file, 'r+') as f:
        content = f.read().replace('abcd', 'efgh')
        f.write(content)

I tried this logic for single file and it is not replacing the content, it is just appending with older content
Yeah, different I/O operations needed, this should work:

for file in files:
    with open(file, 'r') as f:
        content = f.read().replace('abcd', 'efgh')
    with open(file, 'w') as f:
        f.write(content)
Malt Wrote:I tried this logic for single file and it is not replacing the content, it is just appending with older content
Or you could perhaps add a f.seek(0) before the write, and perhaps f.truncate() after the write.
Can use in_place which make it easier the read/write to same place in one go.
import os
import in_place

for files in os.scandir('.'):
    if files.name.endswith('.LIC'):
        with in_place.InPlace(files) as f:
            text = f.read().replace('abcd', 'efgh')
            f.write(text)
(Oct-14-2019, 10:42 AM)snippsat Wrote: [ -> ]Can use in_place which make it easier the read/write to same place in one go.
import os
import in_place

for files in os.scandir('.'):
    if files.name.endswith('.LIC'):
        with in_place.InPlace(files) as f:
            text = f.read().replace('abcd', 'efgh')
            f.write(text)

Idea Angel
This is one of those cases where I wouldn't use Python. In my mind, this is a job for the shell and friends (at least on Unix; if you're on Windows, I can't help you).

Consider two files with some contents in the current directory:

Output:
$ cat first-file foo bar baz $ cat second-file baz qux bar foo bar qux
I can use find to, well, find the files in the current directory, loop over them in the shell (Bash in my case), using sed to, say, replace "bar" with "foo":

Output:
$ for file in $(find . -type f); do sed -i.bak 's/bar/foo/g' $file; done $ cat first-file foo foo baz $ cat second-file baz qux foo foo foo qux
The Grymoire has lots of useful tutorials on these sorts of tools.