繁体   English   中英

如何在文件中搜索字符串并将其替换为Python中的多行?

[英]How do I search a file for a string and replace it with multiple lines in Python?

我正在运行Python 3.5.1

我有一个文本文件,如果与预定义变量匹配,我将尝试搜索并替换或覆盖文本。 下面是一个简单的示例:

test2.txt

A Bunch of Nonsense Stuff
############################
# More Stuff Goes HERE     #
############################
More stuff here
Outdated line of information that has no comment above - message_label

此示例中的最后一行需要覆盖,因此新文件如下所示:

脚本后的test2.txt

A Bunch of Nonsense Stuff
############################
# More Stuff Goes HERE     #
############################
More stuff here

# This is an important line that needs to be copied
Very Important Line of information that the above line is a comment for - message_label

我编写的IdealAppend函数无法按预期运行,后续执行会造成混乱。 我的解决方法是将两行分隔为单行变量,但这伸缩性不好。 我想在整个脚本中使用此功能,并能够处理任意数量的行。 (如果有道理)

脚本

#!/usr/bin/env python3
import sys, fileinput, os
def main():

    file = 'test2.txt'
    fullData = r'''
# This is an important line that needs to be copied
Very Important Line of information that the above line is a comment for - message_label
'''
    idealAppend(file, fullData)


def idealAppend(filename, data):
    label = data.split()[-1]                                            # Grab last word of the Append String
    for line in fileinput.input(filename, inplace=1, backup='.bak'):
        if line.strip().endswith(label) and line != data:               # If a line 2 exists that matches the last word (label)
            line = data                                                 # Overwrite with new line, comment, new line, and append data.
        sys.stdout.write(line)                                          # Write changes to current line

    with open(filename, 'r+') as file:                                  # Open File with rw permissions
        line_found = any(data in line for line in file)                 # Search if Append exists in file

        if not line_found:                                              # If data does NOT exist
            file.seek(0, os.SEEK_END)                                   # Goes to last line of the file
            file.write(data)                                            # Write data to the end of the file


if __name__ == "__main__": main()

解决方法脚本
只要我只需要写两行,这似乎就可以完美地工作。 我希望在行数方面更具动态性,因此我可以轻松地重用该函数。

#!/usr/bin/env python3
import sys, fileinput, os
def main():

    file = 'test2.txt'
    comment = r'# This is an important line that needs to be copied'
    append = r'Very Important Line of information that the above line is a comment for - message_label'

    appendFile(file, comment, append)

def appendFile(filename, comment, append):

    label = append.split()[-1]                                          # Grab last word of the Append String
    for line in fileinput.input(filename, inplace=1, backup='.bak'):
        if line.strip().endswith(label) and line != append:             # If a line 2 exists that matches the last word (label)
            line = '\n' + comment + '\n' + append                       # Overwrite with new line, comment, new line, and append data.
        sys.stdout.write(line)                                          # Write changes to current line

    with open(filename, 'r+') as file:                                  # Open File with rw permissions
        line_found = any(append in line for line in file)               # Search if Append exists in file

        if not line_found:                                              # If data does NOT exist
            file.seek(0, os.SEEK_END)                                   # Goes to last line of the file
            file.write('\n' + comment + '\n' + append)                  # Write data to the end of the file

if __name__ == "__main__": main()

我是Python的新手,所以希望有一个我忽略的简单解决方案。 我认为尝试将新行字符处的fullData变量拆分为列表或元组,从列表中的最后一项过滤标签,然后输出所有条目可能是有意义的,但这已经超出了我的范围到目前为止学到的东西。

如果我正确理解了您的问题,则可以打开输入和输出文件,然后检查该行是否包含旧信息并以标签结尾,并相应地编写适当的内容。

with open('in.txt') as f, open('out.txt', 'r') as output:
    for line in f:
        if line.endswith(label) and not line.startswith(new_info):
            output.write(replacement_text)
        else:
            output.write(line)

如果要更新原始文件而不是创建第二个文件,最简单的方法是删除原始文件并重命名新文件,而不是尝试对其进行修改。

这是你想要的 ? 它正在寻找标签,然后用所需的内容替换整行。

test2.txt

A Bunch of Nonsense Stuff
############################
# More Stuff Goes HERE     #
############################
More stuff here

Here is to be replaced - to_replace

script.py

#!/usr/bin/env python3

def main():
    file = 'test2.txt'
    label_to_modify = "to_replace"
    replace_with = "# Blabla\nMultiline\nHello"
    """
    # Raw string stored in a file
    file_replace_with = 'replace_with.txt'
    with open(file_replace_with, 'r') as f:
        replace_with = f.read()
    """
    appendFile(file, label_to_modify, replace_with)

def appendFile(filename, label_to_modify, replace_with):
    new_file = []
    with open(filename, 'r') as f:
        for line in f:
            if len(line.split()) > 0 and line.split()[-1] == label_to_modify:
                new_file.append(replace_with)
            else:
                new_file.append(line)

    with open(filename + ".bak", 'w') as f:
        f.write(''.join(new_file))

if __name__ == "__main__": main()

test2.txt.bak

A Bunch of Nonsense Stuff
############################
# More Stuff Goes HERE     #
############################
More stuff here

# Blabla
Multiline
Hello

阅读两个答案后,我想出了以下最佳解决方案,这是我可以使用的最佳解决方案。 它似乎做了我需要的一切。 感谢大家。

#!/usr/bin/env python3

def main():

    testConfFile = 'test2.txt' # /etc/apache2/apache2.conf
    testConfLabel = 'timed_combined'
    testConfData = r'''###This is an important line that needs to be copied - ##-#-####
Very Important Line of information that the above line is a \"r\" comment for - message_label'''

    testFormatAppend(testConfFile, testConfData, testConfLabel)     # Add new test format

def testFormatAppend(filename, data, label):
    dataSplit = data.splitlines()
    fileDataStr = ''

    with open(filename, 'r') as file:
        fileData = stringToDictByLine(file)

    for key, val in fileData.items():
        for row in dataSplit:
            if val.strip().endswith(row.strip().split()[-1]):
                fileData[key] = ''

    fileLen = len(fileData) 
    if fileData[fileLen] == '':
        fileLen += 1
        fileData[fileLen] = data
    else:
        fileLen += 1
        fileData[fileLen] = '\n' + data

    for key, val in fileData.items():
        fileDataStr += val

    with open(filename, 'w') as file:
        file.writelines(str(fileDataStr))


def stringToDictByLine(data):
    fileData = {}
    i = 1
    for line in data:
        fileData[i] = line
        i += 1
    return fileData

if __name__ == "__main__": main()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM