1

Here is a problem.

I have a .py file and a .txt. To simplify, my .txt looks like:

@x@

In the .py I have

x=15

I would like to replace @x@ in the txt by the value saved in the py, ie my txt should look like

15

I tried with this:

for i, line in enumerate(fileinput.input('mytxtfile.txt', inplace = 1)):
    sys.stdout.write(line.replace('@x@', 'x'))

or with

for i, line in enumerate(fileinput.input('mytxtfile.txt', inplace = 1)):
    sys.stdout.write(line.replace('@x@', 'str(x)'))

The problem is that the "replace" method seems to consider only strings and I need to evaluate the value of the string. Any idea how to do it?

Thanks

4 Answers 4

9

The string.Template class is a good way to do this.

http://docs.python.org/library/string.html#template-strings

from string import Template
class MyTemplate( Template ): 
    delimiter= '@'
    pattern= r"@(?P<escaped>@)|@(?P<named>[_a-z][_a-z0-9]*)@|@(?P<braced>[_a-z][_a-z0-9]*)@|@(?P<invalid>)"

Given this class definition, you can now do this

with open( 'a.txt', 'r' ) as source:
    t = MyTemplate(source.read())
    result= t.substitute( x=15 )
    print result

This allows you to use any number of substitutions anywhere in the template of almost any complexity. This handles a very, very large number of cases gracefully.

Sign up to request clarification or add additional context in comments.

Comments

7

just leave the quotes off str(x)

for i, line in enumerate(fileinput.input('mytxtfile.txt', inplace = 1)): 
    sys.stdout.write(line.replace('@x@', str(x)))

If you want more control over the output you can use a format string. Eg for 2 decimal places

for i, line in enumerate(fileinput.input('mytxtfile.txt', inplace = 1)): 
    sys.stdout.write(line.replace('@x@', "%.2f"%x))

4 Comments

Thanks, I had tested it but was not using the good txt file since it had been changed from my previous try with quotes, so it didnt work :(
@remi: "not using the good txt file since it had been changed from my previous try with quotes"? What?
@S.Lott He had already run his incorrect code, replacing '@x@' with 'str(x)', so then when he tried to run the correct version (ie without the quotes around str(x)), it didn't work, because there weren't any @x@s in the input text file any more. That's how it reads to me, anyway.
@Cam Jackson: Guessing about their meaning is can be a bad policy. When it's confusing, I prefer to ask for clarification. I find it helpful because I learn more.
0

Not sure whether you need to replace only 'x' or there are other variables in your files, but if so than i think you can also use the following code too:

# preparing dict based on a.py
d1 = {}
for line in open('a.py','r'):
    if line.strip() and '=' in line:
        k,v = line.strip().split('=')
        d1['@' + k + '@'] = v

# preparing data from a.txt using dict from a.py
res = ''
for line in open('a.txt','r'):# lines below can be optimized depending on what you really need
    for k,v in d1.items():
        if k in line:
            line.replace(k, v)
    res += line '\n'

# write modified data
f = open('a.txt', 'w')
f.write(res.rstrip('\n'))
f.close()

Comments

0

Although you have already received nice answers to your problem, there is an alternative way. Use python formatting strings in your text files (e.g. %(x)f or %(x)s). This example shows how it works:

line = '%(x)f or %(x).2f or %(x)s'
x = 15
print line % locals()

You can use a dictionary (e.g. print line % {'x': 15}) instead of locals(). I use it as a quick and dirty way to implement templates in python.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.