行替换问题

时间:2019-02-19 01:06:26

标签: python

我需要用第二个文件中的值替换XML文件。 问题是由于某种原因我的xml文件被完全清除,所有数据都被删除了。 数据应该保留,除非它在XML文件上找到$ {key},则只能将其替换为$ {value}

import os
import progressbar

#VARIABLE TO CONCATENATE WITH THE FILE NAME
home = '/u01/app/oracle/mftxfer_adoc/DAYS/ola/'
#I WILL USE THIS FOLDER TO CHECK FOR FILES WITH THE NAME AJOG
directory = os.listdir('/u01/app/oracle/mftxfer_adoc/DAYS/ola/')

#THIS FILE IS MY FILTER LIST
word_list = open('/u01/app/oracle/mftxfer_adoc/DAYS/teste.txt').readlines()

#FOR EACH FILE THAT ENCOUNTERS ON THE DIRECTORY
for file_xml in directory:
    #IF THE FILENAME HAS AJOG IN IT
    if file_xml.__contains__('AJOG'):
        print("Processing the file"+" "+file_xml)
        #OPENS THE FILE
        file_read = open(home+file_xml, 'r').readlines()
        #NOW WILL CHECK IF THE LINE CONTAINS A SPECIFIC STRING
        for line in file_read:
                if "<codigo>" in line:
                        #IF HAS THEN PICKS THE FILTER
                        for word_list_line in word_list:
                                #DEVIDES THE FILTER IN 2 COLUMNS
                                key = str((word_list_line.split(' ')[0]))
                                value = str((word_list_line.split(' ')[1]))
                                #CHECKS IF THE VALUE FROM THE FIRST COLUMN IN ON THE LINE OF THE AJOG FILE
                                if key in line:
                                        print("Found the value "+key+" on file "+file_xml)
                                        #IF SO THEN REPLACE THE VALUE FROM THE FIRST COLUMN WITH THE SECOND COLUMN
                                        file_read=line.replace(key, value)
                                        #THE SAME FILE IS OPENED IN WRITE MODE
                                        file_write = open(home + file_xml, 'w')
                                        #WRITES THE CHANGES TO THE LINE
                                        file_write.writelines(file_read)

3 个答案:

答案 0 :(得分:0)

在不了解整个程序的上下文的情况下,我注意到您没有关闭文件。有时似乎什么都没写,是因为它们都卡在了缓冲区中并且还没有写,所以请使用file_write.close()或更好的方法,请使用with open(filename, "w")以避免将来发生这种情况。

答案 1 :(得分:0)

处理XML文件,因为文本是一项艰巨的任务。

愿您可以为此使用一个库。

此示例可以指导您采用更好的方法。

import xml.etree.ElementTree

tree = xml.etree.ElementTree.parse("test.xml")

tree.find("some key").text = 'new value'

答案 2 :(得分:0)

删除文件的原因是因为您以写模式重新打开了文件。这样做时,文件将被截断(清除)。请参阅open()说明。可以追加到文件中,但这不是您想要的。

我认为XML解析器(如@andercurzbr答案中所建议)是最好的解决方案。但是,如果您想使用代码,则可以使用fileinput模块,该模块可以快速循环遍历文件的各行。这是您的脚本经过编辑以使用fileinput的示例。它未经测试,但应该可以为您提供提示。

import os
import fileinput

#VARIABLE TO CONCATENATE WITH THE FILE NAME
home = '/u01/app/oracle/mftxfer_adoc/DAYS/ola/'
#I WILL USE THIS FOLDER TO CHECK FOR FILES WITH THE NAME AJOG
directory = os.listdir('/u01/app/oracle/mftxfer_adoc/DAYS/ola/')

#THIS FILE IS MY FILTER LIST
word_list = open('/u01/app/oracle/mftxfer_adoc/DAYS/teste.txt').readlines()

#FOR EACH FILE THAT ENCOUNTERS ON THE DIRECTORY
for file_xml in directory:
    #IF THE FILENAME HAS AJOG IN IT
    if file_xml.__contains__('AJOG'):
        print("Processing the file"+" "+file_xml)
        #NOW WILL CHECK IF THE LINE CONTAINS A SPECIFIC STRING WITH FILEINPUT
        for line in fileinput.input(home+file_xml, inplace=True):
            if "<codigo>" in line:
                #IF HAS THEN PICKS THE FILTER
                for word_list_line in word_list:
                    #DEVIDES THE FILTER IN 2 COLUMNS
                    key = str((word_list_line.split(' ')[0]))
                    value = str((word_list_line.split(' ')[1]))
                    #CHECKS IF THE VALUE FROM THE FIRST COLUMN IN ON THE LINE OF THE AJOG FILE
                    if key in line:
                        #print("Found the value "+key+" on file "+file_xml)
                        #IF SO THEN REPLACE THE VALUE FROM THE FIRST COLUMN WITH THE SECOND COLUMN
                        file_read=line.replace(key, value)
                        #WRITES THE CHANGES TO THE LINE
                        print(file_read)
                    else:
                        print(line)
            else:
               print(line)

请注意,使用inplace=True选项时,输出将重定向到文件本身。从文档中:

  

如果关键字参数inplace = True传递给fileinput.input()或   到FileInput构造函数,该文件将移至备份文件,然后   标准输出定向到输入文件(如果文件相同)   名称,因为备份文件已经存在,它将被静默替换)。   这样就可以编写一个重写其输入文件的过滤器   就位。

这意味着在调用print()之后调用的fileinput.input(home+file_xml, inplace=True)函数将写入文件。未编辑的行也必须打印,否则会丢失,这就是为什么我添加了两个else