-1

I want to replace a specific string in a file by a variable's value:

In my file there is these 2 lines:

<CtrlSum>10</CtrlSum>
<sum>45</sum>

I want to search for the value "10" and replace it by "45".

I tried something like that:

with open(path,'r+') as f:
    lst=f.readlines()
    for j in lst:
        if'sum' in j:
            Somme = j.split('>')[1].split('<')[0]
            print(Somme)

    for i in lst:
        if 'CtrlSum' in i:
            Ctrl = i.split('>')[1].split('<')[0]
    print (Ctrl)

    f.writelines(f.replace(Ctrl,Somme))

But I have this error:

f.writelines(f.replace(Ctrl,Somme)) AttributeError: '_io.TextIOWrapper' object has no attribute 'replace'

What is wrong and how can I fix it?

8
  • f is a file. You can only call .replace() on a string (i.e. the result of .read()) Commented Sep 15, 2020 at 12:30
  • Usually I create another file, copy the modified content to it and then rename it to override the original Commented Sep 15, 2020 at 12:30
  • what are you trying to do? replace what string with what? - what are you planning to achieve with these splits? Commented Sep 15, 2020 at 12:31
  • i want to replace the value between < > on "CtrlSum" by value of "Sum" @DevCl9 Commented Sep 15, 2020 at 12:33
  • Are you asking how to parse an XML or HTML file? Commented Sep 15, 2020 at 12:49

4 Answers 4

1

You can simply do something like this:

import re

with open('a.txt','r') as f:
    text_value = f.read()

    sum_val = sum(map(int, re.findall(r'<sum>(\d+)</sum>', text_value)))

with open('a.txt','w') as f:
    f.write(re.sub(r'<CtrlSum>(.+)</CtrlSum>', f'<CtrlSum>{sum_val}</CtrlSum>', text_value))

No need for readlines() or writelines() or any loop. Just read the whole text with .read() -> process it -> write().

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

8 Comments

Yeah but without readlines() i cant loop trough my files to seek different occurences of what i am searching for : in this case value between <> after "CtrlSum" String @DevCl9
WDYM? could you share a sample input file and the desired output? (if this code doesn't cut it)
imagine if in my file there is these 2 lines : <CtrlSum>10</CtrlSum> <sum>45</sum> i want to search for the value "10" and replace it by "45" , sorry if its not very clear ! @DevCl9
Yeah ! but that append all the text after the first one , is there a way to overwrite it ?
Yeah but if there is multiple occurence of "Sum" is there any way to add them ?@DevCl9
|
0

The replace() function can only be used on a string. Your f isn't a string, it's the file itself. You need to call f.read() to get the file content as a string and call replace() on this.

EDIT: Check this link, it explains different methods to write on files :)

https://pythonexamples.org/python-replace-string-in-file/

Comments

0

Use XML parsing

import xml.etree.ElementTree as ET

xml = '''<r><CtrlSum>10</CtrlSum>
<sum>45</sum></r>'''

root = ET.fromstring(xml)
root.find('.//CtrlSum').text = root.find('.//sum').text
ET.dump(root)

output

<r>
   <CtrlSum>45</CtrlSum>
   <sum>45</sum>
</r>

2 Comments

But is this solution will work when the xml file will have a lot of element and child and subchild ? or is it just working with this example ?@balderman
Try it on your xml and give feedback
0

XSLT 3.0 solution:

<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:mode on-no-match="shallow-copy"/>
 <xsl:template match="CtrlSum/text()">
   <xsl:value-of select="//sum"/>
 </xsl:template>
</xsl:transform>

(Using XSLT 1.0 is also possible, just a bit more verbose).

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.