0

I'm new to python and am using version 2.7

I would like to replace the string inside a file using a wild card that fills out the rest of that line. Here is what I have so far...

This will work and change the file string to second string:

if line == 'This = first string':
    line = 'This = second string'

This will not work and the file string will remain as first string:

if line == 'This = *':
    line = 'This = second string'

Full Script:

import sys
import shutil
import os
import re

#Assigns tf as a tmp file with the module for appending and writing, and creating the file if it does not exist.
tf = open('tmp', 'a+')

#Assigns f as test.txt
with open('test1.txt') as f:
#Reads the line in the test1.txt file
    for line in f.readlines():
#Checks for the line condition
        if line == 'This = *':
#Sets the new line condition
            line = 'This = second string'
#Replaces the line withe the new build path
        tf.write(line)
#Closes the test2.txt file
f.close()
tf.close()
#Copies the changes from the tmp file and replaces them into the test2.txt
shutil.copy('tmp', 'test2.txt')
#Removies the tmp file from the computer
os.remove('tmp')

Latest Code for J.F. Sebastian

test2.txt contents:

blah
This = first string

testing2.py contents:

import os
from tempfile import NamedTemporaryFile

prefix = "This = "
path = 'test2.txt'  
dirpath = os.path.dirname(path)
with open(path) as input_file:
    with open(path+".tmp", mode="w") as tmp_file:
        for line in input_file:
            if line.startswith(prefix):
                line = prefix + "second string\n"
            tmp_file.write(line)
        tmp_file.delete = False
os.remove(path)
os.rename(tmp_file.name, path)

Error Message:

C:\Users\james>testing2.py
Traceback (most recent call last):
  File "C:\Users\james\testing2.py", line 13, in <module>
    tmp_file.delete = False
AttributeError: 'file' object has no attribute 'delete'

Any Suggestions?

Fiddle Freak
  • 1,923
  • 5
  • 43
  • 83
  • What have you tried to fix the `AttributeError`? What do you expect `tmp_file.delete = False` line to do? Why is it there? – jfs Apr 08 '13 at 14:26

2 Answers2

1

To replace lines that start with the prefix:

prefix = "This = "
if line.startswith(prefix):
    line = prefix + "second string"

If the file is a config file with key = value lines then you could also replace the value using line.partition() method, ConfigParser module, or regular expressions (in more complex cases):

import re
# ...
line = re.sub(r"^This\s*=.*$", "This = second string", line)

To replace lines in a file; you could use fileinput module or just write to a temporary file (tempfile.NamedTemporaryFile) and rename it at the end:

#!/usr/bin/env python
import os
from tempfile import NamedTemporaryFile

prefix = "This = "
path = 'test1.txt'  
dirpath = os.path.dirname(path)
with open(path) as input_file:
    with NamedTemporaryFile(mode="w", dir=dirpath) as tmp_file:
        for line in input_file:
            if line.startswith(prefix):
                line = prefix + "second string\n"
            tmp_file.write(line)
        tmp_file.delete = False
os.remove(path)
os.rename(tmp_file.name, path)
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • I'm getting an error `expected an indented block` for the `prefix` or `line`. I updated the full script so maybe you could get a clearer picture – Fiddle Freak Apr 08 '13 at 02:49
  • @FiddleFreak: Post the code that raises the error with the full traceback. Check that you don't mix tabs and spaces. – jfs Apr 08 '13 at 02:59
  • Posted it, awaiting response... – Fiddle Freak Apr 08 '13 at 03:08
  • @FiddleFreak: I've added complete code example. – jfs Apr 08 '13 at 03:19
  • still not working. I got an error for the last line `WindowsError: [Error 2] The system cannot find the file specified` – Fiddle Freak Apr 08 '13 at 04:00
  • @FiddleFreak: I've updated the code to remove the file before the `rename` call which fails on Windows if a destination file exists already. Though the error message would've been different. Check that `tmp_file.delete` line is indented properly. – jfs Apr 08 '13 at 04:58
  • Same error, only this time it is deleting the file. – Fiddle Freak Apr 08 '13 at 05:02
  • @FiddleFreak: Post the code that raises the error with the full traceback. Make sure the indentation is correct. – jfs Apr 08 '13 at 05:06
  • Updated for review... – Fiddle Freak Apr 08 '13 at 05:14
  • @FiddleFreak: the code should work. Try `with open(path+".tmp", "w") as tmp_file:` instead of `NamedTemporaryFile`. – jfs Apr 08 '13 at 05:38
  • I updated the error for you... – Fiddle Freak Apr 08 '13 at 13:56
  • I just got an idea. Would there be a way to do this: if line contains prefix, set linenumber. linenumber.remove (this will remove everything in that line). linenumber.write 'This = second string' – Fiddle Freak Apr 08 '13 at 14:37
0

I finally found the answer...

test1.txt before Nightly.py executed:

blah
blah
This is a first string
blah
blah

BTW tabs make a difference in the code with notepad++

import sys
import os
import re
import shutil

tf = open('tmp', 'a+')

with open('test1.txt') as f:
    for line in f.readlines():
        build = re.sub ('This is.*','This is a second string',line)
        tf.write(build)
tf.close()
f.close()
shutil.copy('tmp', 'test1.txt')
os.remove('tmp')

test1.txt after Nightly.py executed:

blah
blah
This is a second string
blah
blah
Fiddle Freak
  • 1,923
  • 5
  • 43
  • 83