user88720
user88720

Reputation: 342

Why won't this Python script replace one variable with another variable?

I have a CSV file with two columns in it, the one of the left being an old string, and the one directly to right being the new one. I have a heap of .xml files that contain the old strings, which I need to replace/update with the new ones.

The script is supposed to open each .xml file one at a time and replace all of the old strings in the CSV file with the new ones. I have tried to use a replace function to replace instances of the old string, called 'column[0]' with the new string, called 'column[1]'. However I must be missing something as this seems to do nothing. If I the first variable in the replace function to an actual string with quotation marks, the replace function works. However if both the terms in the replace function are variables, it doesn't.

Does anyone know what I am doing wrong?

import os
import csv

with open('csv.csv') as csv:
    lines = csv.readline()
    column = lines.split(',')

    fileNames=[f for f in os.listdir('.') if f.endswith('.xml')]
    for f in fileNames:
        x=open(f).read()
        x=x.replace(column[0],column[1])
        print(x)

Example of CSV file:

oldstring1,newstring1
oldstring2,newstring2

Example of .xml file:

Word words words oldstring1 words words words oldstring2

What I want in the new .xml files:

Word words words newstring1 words words words newstring2

Upvotes: 0

Views: 253

Answers (2)

gboffi
gboffi

Reputation: 25093

It looks like this is better done using sed. However.

If we want to use Python, it seems to me that what you want to do is best achieved

  • reading all the obsolete - replacements pairs and store them in a list of lists,
  • have a loop over the .xml files, as specified on the command line, using the handy fileinput module, specifying that we want to operate in line and that we want to keep around the backup files,
    • for every line in each of the .xml s operate all the replacements,
    • put back the modified line in the original file (using simply a print, thanks to fileinput's magic) (end='' because we don't want to strip each line to preserve eventual white space).
import fileinput
import sys

old_new = [line.strip().split(',') for line in open('csv.csv')]

for line in fileinput.input(sys.argv[1:], inplace=True, backup='.bak'):
    for old, new in old_new:
        line = line.replace(old, new)
    print(line, end='')

If you save the code in replace.py, you will execute it like this

$ python3 replace.py *.xml subdir/*.xml another_one/a_single.xml

Upvotes: 1

Keval Dave
Keval Dave

Reputation: 2987

The problem over here is you are treating the csv file as normal text file not looping over the all the lines in the csv file.

You need to read file using csv reader

Following code will work for your task

import os
import csv
with open('csv.csv') as csvfile:
    reader = csv.reader(csvfile)
    fileNames=[f for f in os.listdir('.') if f.endswith('.xml')]
    for f in fileNames:
        x=open(f).read()
        for row in reader:
            x=x.replace(row[0],row[1])
        print(x)

Upvotes: 1

Related Questions