在字符串匹配后将行插入到文件中

use*_*674 5 python python-2.7

我试图在文件的行中搜索子字符串,并在找到的行之后立即插入类似的行。尽管有使用该fileinput方法的类似解决方案,但我不知道如何在我的案例中使用它。

这是我尝试过的:

list = ["abc", "pqr", "xyz"]

inputfile = open (somefile.txt, 'a+')
for line in <inputfile>:    
    if 'stringstosearch' in line:
       for <item> in list:
               new_line = "new_line with %s" %(item)        
               inputfile.write(new_line + "\n") 
    break
inputfile.close()
Run Code Online (Sandbox Code Playgroud)

例如,如果文本文件是:

Torquent scelerisque aptent hac rhoncus vel
Turpis 前庭 Tellus laoreet mollis conubia facilisis tempor nec semper
In mi mauris etiam quisque sem congue est velit lacus convallis amet ante ad
Integer maecenas semper quisque nisi hendrerit, 自由人 feugiat cursus euismod Accumsan
Dui sed麦格纳·维瓦穆斯·奥格·阿克·基斯克·阿克毛里斯·
托克恩·爱洛斯·默契·库努比亚·库拉·维尔·希梅内奥斯的名言 sed at

string to search = "mauris etiam quisque"
list = ["abc", "pqr", "xyz" ]
Run Code Online (Sandbox Code Playgroud)

文件写入后的预期输出:

扭矩 aptent hac rhoncus vel
Turpis 前庭 Tellus laoreet mollis conubia facilisis tempor nec semper
In mi mauris etiam quisque sem congue est velit lacus convallis amet ante ad
new_line with abc
new_line with pqr
new_line with xyz
Integer maecenas semper quisque nisi hendrerit, lib ero feugiat 诅咒 euismod Accumsan
Dui sed magna vivamus augue ac quisque ac mauris Tornt eros taciti
Conubia curae vel Himenaeos dictumst sed at

aba*_*ert 4

通常不能插入到文件的中间。*

对此的通用解决方案是复制到一个新文件,在复制过程中插入,然后将新文件移到旧文件之上。例如:

with tempfile.NamedTemporaryFile('w', delete=False) as outfile:
    with open(inpath) as infile, 
        for line in infile:
            outfile.write(line)
            if needs_inserting_after(line):
                outfile.write(stuff_to_insert_after(line))
os.replace(outfile.name, inpath)
Run Code Online (Sandbox Code Playgroud)

请注意,os.replacePython 2.7 中不存在。如果你不关心Windows,你可以使用os.rename它。如果你这样做,我强烈建议你寻找os.replacePyPI 的向后移植;至少有两个。否则,您必须了解 Windows 上独占锁和原子移动的整个混乱情况。

还有一些更高级别的库可以为您包装整个事情。(我写了一个名为的代码fatomic,我认为它可以作为很好的示例代码,但我不确定如果没有进行更多测试,我是否会相信它用于生产代码。我确信如果您搜索 PyPI,您可以找到其他替代方案。)


当然还有其他选择:

您可以将原始文件移动到备份路径,然后将其复制到正常路径的新文件中,而不是复制到临时路径的新文件然后事后移动。这样做的缺点是,如果中途失败,会留下半个文件,但优点是不需要处理 Windows 上的独占锁问题。这实际上就是自动化为您fileinput.FileInput所做的事情inplace=True

您可以将整个文件读入内存,在内存中处理它,然后将整个文件写回。这样做的优点是非常简单,不需要任何额外的文件,并且意味着如果有人拥有您的文件的文件句柄(而不是路径名),他们会在您完成后看到新版本。但最后一个可能是一个缺点。当然,这意味着您需要足够的内存来同时保存所有数据。

最后,在写入 N 个字节之前,您始终可以将整个文件从当前位置向上移动 N 个字节。这具有上述两者的大部分优点,但也很混乱且缓慢。


* 为什么我在那里说“一般”?好吧,最终,文件系统必须有某种方法在文件中间插入新块。某些文件系统会将其公开给用户级别。一些较旧的平台曾经在此基础上构建了用户级功能,例如 Apple ][ ProDOS 上的“随机访问文本文件”或我在 VMS 中忘记的东西。因此,从字面上看,您不能插入到文件的中间并不是真的。在您关心的每种情况下都是如此。