1

Here below is my code about how to edit text file.

Since python can't just edit a line and save it at the same time,

I save the previous text file's content into a list first then write it out.

For example,if there are two text files called sample1.txt and sample2.txt in the same folder.

Sample1.txt
A for apple.

Second line.

Third line.

Sample2.txt
First line.

An apple a day.

Third line.

Execute python

import glob
import os

#search all text files which are in the same folder with python script
path = os.path.dirname(os.path.abspath(__file__))
txtlist = glob.glob(path + '\*.txt')

for file in txtlist:
    fp1 = open(file, 'r+')
    strings = [] #create a list to store the content
    for line in fp1:
        if 'apple' in line:
            strings.append('banana\n') #change the content and store into list
        else:
            strings.append(line) #store the contents did not be changed
    fp2 = open (file, 'w+') # rewrite the original text files
    for line in strings:
        fp2.write(line)
    fp1.close()
    fp2.close()

Sample1.txt
banana

Second line.

Third line.

Sample2.txt
First line.

banana

Third line.


That's how I edit specific line for text file.

My question is : Is there any method can do the same thing?

Like using the other functions or using the other data type rather than list.

Thank you everyone.

Yuan Chang
  • 21
  • 3
  • If you use `read` you can read the entire file into a string variable and do the substitution there. If you don't want to store the strings in memory at all then you can step through the input line by line and immediately write it out to a second file. But you can't update the file you are reading so you end up with two files. It is then up to your code to delete the old one and rename the new one. You can use the module `in_place` https://pypi.org/project/in-place/ to let your code pretend that it is updating the file it is reading, in place. – BoarGules Feb 20 '19 at 08:18
  • You can use the `fileinput` module to do this. There's a description of how to in [this](https://stackoverflow.com/questions/5453267/is-it-possible-to-modify-lines-in-a-file-in-place) answer. – Noufal Ibrahim Feb 20 '19 at 08:28

4 Answers4

1

Simplify it to this:

with open(fname) as f:
    content = f.readlines()
    content = ['banana' if line.find('apple') != -1 else line for line in content]

and then write value of content to file back.

kosist
  • 2,868
  • 2
  • 17
  • 30
0

Instead of putting all the lines in a list and writing it, you can read it into memory, replace, and write it using same file.

def replace_word(filename):
    with open(filename, 'r') as file:
       data = file.read()

    data = data.replace('word1', 'word2')

    with open(filename, 'w') as file:
        file.write(data)

Then you can loop through all of your files and apply this function

Onur A.
  • 3,007
  • 3
  • 22
  • 37
  • Thanks for your answering first.If I wanna replace the lines that contain apple not just "apple",what should I do with replace function? – Yuan Chang Feb 20 '19 at 08:29
0

The built-in fileinput module makes this quite simple:

import fileinput
import glob

with fileinput.input(files=glob.glob('*.txt'), inplace=True) as files:
    for line in files:
        if 'apple' in line:
            print('banana')
        else:
            print(line, end='')

fileinput redirects print into the active file.

iz_
  • 15,923
  • 3
  • 25
  • 40
0
import glob
import os


def replace_line(file_path, replace_table: dict) -> None:
    list_lines = []
    need_rewrite = False
    with open(file_path, 'r') as f:
        for line in f:
            flag_rewrite = False
            for key, new_val in replace_table.items():
                if key in line:
                    list_lines.append(new_val+'\n')
                    flag_rewrite = True
                    need_rewrite = True
                    break  # only replace first find the words.

            if not flag_rewrite:
                list_lines.append(line)

    if not need_rewrite:
        return

    with open(file_path, 'w') as f:
        [f.write(line) for line in list_lines]


if __name__ == '__main__':
    work_dir = os.path.dirname(os.path.abspath(__file__))
    txt_list = glob.glob(work_dir + '/*.txt')
    replace_dict = dict(apple='banana', orange='grape')

    for txt_path in txt_list:
        replace_line(txt_path, replace_dict)
Carson
  • 6,105
  • 2
  • 37
  • 45