【问题标题】:How to insert a specific string into a specific location of a specific line in a file using a Python script?如何使用 Python 脚本将特定字符串插入文件中特定行的特定位置?
【发布时间】:2015-03-02 20:14:04
【问题描述】:

'file.txt' 中有这样一行字:

memcpy(buffer, "", 64)

我想编写一个 Python 脚本来读取这个file.txt 并在其中找到这一行。然后,它继续在该行的两个引号 ("") 之间插入一个特定字符串(存储在变量 'data' 中)。

例如,如果变量 data 包含值 'foo bar',则 Python 脚本将修改该行为:

memcpy(buffer, "foo bar", 64)

这是我尝试过的:

data = "foo bar"

with open('file.txt') as in_file:
    in_buffer = in_file.readlines()

with open('new.txt', "w") as out_file:
    for line in in_buffer:
        if line == 'memcpy(buffer, "", 64)':
            out_file.write("memcpy(buffer, \"data\", 64)")
        else:
            out_file.write(line)

它不起作用,因为它在 new.txt 中创建了完全相同的文件副本,而没有进行任何修改。

【问题讨论】:

  • @PeterWood 我确实看过这些问题。参考这些答案后,我确实编写了代码。但是,我无法让它工作。
  • 该行的末尾会有一个换行符。 line == 'memcpy(buffer, "", 64)\n'
  • $ sed 's/^wrong line$/wrong corrected line/' < file.txt > file.new

标签: python string file-io


【解决方案1】:

请使用

if line == 'memcpy(buffer, "", 64)\n':
     out_file.write('memcpy(buffer, "'+data+'", 64)\n')

而不是你的

if line == 'memcpy(buffer, "", 64)':
        out_file.write("memcpy(buffer, \"data\", 64)")

因为readlines() 方法不会删除换行符。

Post Scriptum请注意,不仅条件必须重写,而且您的if 正文也需要重新设计,您的版本会写

memcpy(缓冲区, "数据", 64)

到输出文件。

【讨论】:

    【解决方案2】:

    使用the above comment by Peter Wood 中的建议对您的问题的另一个答案

    使用如下所示的代码

    $ cat mod_memcpy.py
    from fileinput import input
    data = "Papa Smurf"
    for line in input(inline=1, backup=".bak"):
        if line != 'memcpy(buffer, "", 64)\n':
            print line, # << note the comma
        else:
           print 'memcpy(buffer, "'+data+'", 64)'
    

    以下方式

    $ python2 mod_memcpy.py file.txt
    

    您将获得一个备份文件,file.bak file.txt.bak 和修改后的 file.txt

    memcpy(buffer, "", 64)
    

    替换为

    memcpy(buffer, "Papa Smurf", 64)
    

    fileinput 的参考文档是 here (Python 2) 或 here (Python3)。

    我想补充一点,fileinput 模块是此类问题的答案,即修改文件或文件序列。


    附录从外壳复制并粘贴以下内容(稍作编辑以缩短文件...)

    $ cat c.py
    from __future__ import print_function
    from fileinput import input
    for line in input(inplace=True, backup='.bak'):
        print("00", line, end="")
    $ cat dele.txt # the real file is a bit longer, hence the ellipsis
    Company ABC-GH Date:31.12.2012
    financial statement:4
    ...
    $ python2 c.py dele.txt
    $ cat dele.txt
    00 Company ABC-GH Date:31.12.2012
    00 financial statement:4
    ...
    $ mv dele.txt.bak dele.txt
    $ python3 c.py dele.txt
    $ cat dele.txt
    00 Company ABC-GH Date:31.12.2012
    00 financial statement:4
    ...
    $ mv dele.txt.bak dele.txt
    

    似乎代码的相关部分,即,

    for line in input(inline=1, backup=".bak"):
    

    同样适用于 Python 2.7 和 Python 3.4,我不得不承认我不明白 OP 在我的代码中遇到问题的原因是什么。

    【讨论】:

    • 尝试执行它;得到这个:“回溯(最近一次调用最后一次):文件“replace.py”,第 4 行,在 中的输入行(内联 = 1,备份 =“.bak”):类型错误:输入()不接受关键字参数”
    【解决方案3】:

    此代码将条件部分添加到喇叭代码中。 使用 re modules 子函数替换匹配的字符串。

    import re
    
    filename = "file.txt"
    regex = re.compile(r'(memcpy\s*\(\s*buffer\s*,\s*")\s*("\s*,\s*64\s*)')
    with open(filename) as in_file:
        in_buffer = in_file.readlines()
    
    data = "foo bar"
    with open(filename, "w") as out_file:
        for line in in_buffer:
            out_file.write(regex.sub(r'\g<1>'+data+'\g<2>', line))
    

    【讨论】:

    • 您的代码有效!但是,您在最后一行硬编码了值“foo bar”。我希望能够插入存储在“数据”变量中的任何值。我该怎么做?
    • @intellikid 你需要去尝试一下,然后再问一个问题如果你搜索后仍然卡住。
    • 是的,它是硬编码的。现在固定为变量值。这是一个简单的解决方法:只需通过连接两个字符串来创建替换模式。
    【解决方案4】:
    with open(filename) as in_file:
        in_buffer = in_file.readlines()
    
    with open(filename, "w") as out_file:
        for line in in_buffer:
            if condition:
                out_file.write("something else")
            else:
                out_file.write(line)
    

    【讨论】:

    • 谢谢。我刚刚尝试了您的代码(请参阅对上述问题所做的编辑)。这一次它创建了文件的精确副本并且没有进行修改。我猜我指定的条件有问题。您能否建议如何指定条件?
    • 只需将condition 替换为line == 'memcpy(buffer, "", 64)' 或任何你想要的。
    猜你喜欢
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    相关资源
    最近更新 更多