Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to replace (update) text in a file line by line

Tags:

python

I am trying to replace text in a text file by reading each line, testing it, then writing if it needs to be updated. I DO NOT want to save as a new file, as my script already backs up the files first and operates on the backups.

Here is what I have so far... I get fpath from os.walk() and I guarantee that the pathmatch var returns correctly:

fpath = os.path.join(thisdir, filename)
with open(fpath, 'r+') as f:
    for line in f.readlines():
        if '<a href="' in line:
            for test in filelist:
                pathmatch = file_match(line, test)
                    if pathmatch is not None: 
                        repstring = filelist[test] + pathmatch
                        print 'old line:', line
                        line = line.replace(test, repstring)
                        print 'new line:', line
                        f.write(line)

But what ends up happening is that I only get a few lines (updated correctly, mind you, but repeated from earlier in the file) corrected. I think this is a scoping issue, afaict.

*Also: I would like to know how to only replace the text upon the first instance of the match, for ex., I don't want to match the display text, only the underlying href.

like image 426
jml Avatar asked Jan 24 '11 04:01

jml


People also ask

How do I replace data in a text file?

1) Copy all the text up to the start of the line before which you want to insert the new line from the old file to the new file. 2) Write your new text to the new file, with a newline character at the end. 3) Copy all the text up to the end of the file from the old file to the new file. 4) Close both files.

How do you modify a line in a file using Python?

We will first open the file in read-only mode and read all the lines using readlines(), creating a list of lines storing it in a variable. We will make the necessary changes to a specific line and after that, we open the file in write-only mode and write the modified data using writelines().

How do you overwrite a line in a text file in Python?

Method 1: Loop Through Each Line and Use the string. replace() Method. The most straightforward way to replace a specific line in a file is to loop through each line in the text file and find the text/string that has to be replaced and then replace it with the new string using the replace() method.

How do you append to a specific line in Python?

Open the file in append mode ('a'). Write cursor points to the end of file. Append '\n' at the end of the file using write() function. Append the given line to the file using write() function.


2 Answers

First, you want to write the line whether it matches the pattern or not. Otherwise, you're writing out only the matched lines.

Second, between reading the lines and writing the results, you'll need to either truncate the file (can f.seek(0) then f.truncate()), or close the original and reopen. Picking the former, I'd end up with something like:

fpath = os.path.join(thisdir, filename)
with open(fpath, 'r+') as f:
    lines = f.readlines()
    f.seek(0)
    f.truncate()
    for line in lines:
        if '<a href="' in line:
            for test in filelist:
                pathmatch = file_match(line, test)
                    if pathmatch is not None: 
                        repstring = filelist[test] + pathmatch
                        line = line.replace(test, repstring)
        f.write(line)
like image 180
Raph Levien Avatar answered Oct 25 '22 19:10

Raph Levien


  1. Open the file for read and copy all of the lines into memory. Close the file.
  2. Apply your transformations on the lines in memory.
  3. Open the file for write and write out all the lines of text in memory.

with open(filename, "r") as f:
    lines = (line.rstrip() for line in f)
    altered_lines = [some_func(line) if regex.match(line) else line for line in lines]
with open(filename, "w") as f:
    f.write('\n'.join(altered_lines) + '\n')
like image 40
hughdbrown Avatar answered Oct 25 '22 19:10

hughdbrown