【问题标题】:Inserting a file's text into another file at a specific line将文件的文本插入到另一个文件的特定行
【发布时间】:2016-06-06 08:16:18
【问题描述】:

我有两个文本文件 test1.txttest2.txt。我希望能够读取test1.txt 的内容并将其写入text2.txt 的特定行。

我已经能够读取test1.txt 的内容并将它们写入空白test2.txt

现在我想更改我的代码以读取test1.txt 的上下文并将它们写入非空text2.txt

with open("/test1.txt") as f:
    lines = f.readlines()

with open("/test2.txt", "w") as f1:
    f1.writelines(lines)

如何在第 20 行将test1.txt 的内容插入到test2.txt

【问题讨论】:

  • 它被问了很多次,这是互联网上最常见的问题之一,我讨厌听起来像个混蛋,但是你有谷歌“合并两个文件 python”吗?
  • @Torxed:​​​​​​​​​​​​​​嗯,OP说:如何将test1.txt的内容插入test2.txt at第 20 行。
  • @KevinGuan Yea 和谷歌(在我的手机上,所以找到完美代码的工作量很小):stackoverflow.com/q/1325905/929999
  • @Torxed:​​​​​​​​​​​​​​不,这也是一个不同的问题。您链接的问题是试图现在我想在'foo1 bar3''foo2 bar4' 之间插入'foo bar'

标签: python


【解决方案1】:

简单但有点占用内存:

# insert contents of "/test1.txt" into "/test2.txt" at line 20
with open("/test1.txt", "r") as f1:
    t1 = f1.readlines()
with open("/test2.txt", "r") as f2:
    t2 = f2.readlines()
t2.insert(20, t1)
with open("/test2.txt", "w") as f2:
    f2.writelines(t2)

最大限度地减少内存使用和磁盘写入,但有点复杂:

# insert contents of "/test1.txt" into "/test2.txt" at line 20
with open("/test2.txt", "rw+") as f2:
    for x in range(20):
        f2.readline()   # skip past early lines
    pos = f2.tell() # remember insertion position
    f2_remainder = f2.read()    # cache the rest of f2
    f2.seek(pos)
    with open("/test1.txt", "r") as f1:
        f2.write(f1.read())
    f2.write(f2_remainder)

我还没有测试过这两种方法,但它们应该能让你大部分时间到达那里。

【讨论】:

  • 第二种解决方案有效,但 f2.read() 应该是 f2.readline()
  • @MatthiasFripp,这是一个错误。 f2.write(f1.read()) IOError: [Errno 9] 错误的文件描述符
  • @HamadHassan 听起来您可能在with open(...) as f2: 块完成后运行该语句。您确定 f2 在您的代码中是一个打开的文件描述符吗?
  • 如果插入结构也是列表,则解决方案 1 不起作用。因此,不要使用insert(),而是使用stackoverflow.com/a/3748092/11082684 中解释的切片 - 用于在20 行之后插入:t2[20:20] = t1;使用来自stackoverflow.com/q/7138686/11082684 的解决方案也可以使用with open("/test2.txt", "w") as f2:f2.write("\n".join(t2)) 插入换行符
  • 其实第二种方案也是错误的,你想要r+模式,但除此之外,它的写东西顺序不对。
【解决方案2】:

实际上两个已接受答案中的解决方案都已损坏(!)

这是seektell版本的固定版本:

with open("test2.txt", "r+") as f2:
    for x in range(20):
        f2.readline()
    pos = f2.tell()
    f2_remainder = f2.read()
    f2.seek(pos)
    with open("test1.txt", "r") as f1:
        for line in f1:
            f2.write(line)
    f2.write(f2_remainder)

如果输入文件很大并且您需要将其保存在内存中,它仍然会占用大量内存,但在现代计算机上,即使是千兆字节大小的文件,这也应该是可行的。

演示:https://ideone.com/UrOVmx(包括接受的答案如何错误的演示,以及 pavol.kutaj 答案的部署。)

【讨论】:

    【解决方案3】:

    这个问题可能有多种解决方案。一种可能的解决方案是。

    1. 打开 file1 并将内容读取到列表中
    2. 打开 file2 并将内容读取到另一个列表
    3. 在 file2 中的所需位置添加 file1 的内容。
    4. 在 file2 的第二个列表中写回内容。

    【讨论】:

      【解决方案4】:

      试试这个,如果你想在特定行写入一个文件的数据,那么试试这个

      fp = open("data.txt","r")
      # fp is file1
      data = fp.read()
      f = open('workfile.txt', 'rw+')
      #f is file2 on which you want to write data
      ss = f.readlines()
      f.seek(0)
      f.truncate()
      ss.insert(5,data)
      #give your own line number instead of 5
      f.write(''.join(ss))
      

      【讨论】:

        【解决方案5】:

        如果您需要在包含特定子字符串第一次出现的行之后插入并且您不知道(不想依赖)确切的行号:

        • 将您的数据放入source.txt(待充实)和insert.txt(待充实)中。
        import json
        
        
        def main():
            with open("source.txt", mode="rt", encoding="utf-8") as f1:
                source_list = [line for line in f1.readlines()]
        
            with open("insert.txt", mode="rt", encoding="utf-8") as f2:
                insert_list = [line for line in f2.readlines()]
        
            pos = [i for i, line in enumerate(source_list) if '<substring>' in line][0]
            source_list[pos: pos] = insert_list
        
            with open("source.txt", mode="wt", encoding="utf-8") as f1:
                f1.write("".join(source_list))
        
        
        if __name__ == "__main__":
            main()
        

        【讨论】:

        • 感谢您的澄清。无论如何,tell + seek 解决方案可能更可取,但工作代码总是好的。
        • .index() 仅在行的内容在您要查找的行之前是合理唯一的情况下才能工作。将读取分为两个阶段应该不难,这样您就可以跟踪插入点之前的子字符串的索引,而无需再次扫描字符串。
        猜你喜欢
        • 2017-04-23
        • 1970-01-01
        • 2013-04-23
        • 2011-04-16
        • 1970-01-01
        • 2012-04-20
        • 1970-01-01
        • 1970-01-01
        • 2017-07-21
        相关资源
        最近更新 更多