4

我有一个文件,其中包含一些代码行,后跟一个字符串模式。我需要在文件一中包含字符串模式的行之前写下所有内容,在文件二中写下字符串模式之后的所有内容:

例如(文件内容)

  • 代码行 1
  • 代码行 2
  • 字符串模式
  • 代码行 3

输出应该是带有代码行 1、代码行 2 的文件 1 和带有代码行 3 的文件 2。

对写文件比较熟悉,可惜不知道如何判断字符串模式前后的内容。

4

7 回答 7

9

如果输入文件适合内存,最简单的解决方案是使用str.partition()

with open("inputfile") as f:
    contents1, sentinel, contents2 = f.read().partition("Sentinel text\n")
with open("outputfile1", "w") as f:
    f.write(contents1)
with open("outputfile2", "w") as f:
    f.write(contents2)

这假设您知道分隔这两个部分的行的确切文本。

于 2012-06-13T18:20:47.740 回答
5

这种方法类似于Lev 的itertools方法,但因为它很有趣而使用。

 dont_break = lambda l: l.strip() != 'string_pattern'

 with open('input') as source:
     with open('out_1', 'w') as out1:
         out1.writelines(itertools.takewhile(dont_break, source))
     with open('out_2', 'w') as out2:
         out2.writelines(source)

如果需要,您可以用正则表达式或其他任何东西替换 dont_break 函数。

于 2012-06-13T18:29:55.117 回答
3
with open('data.txt') as inf, open('out1.txt','w') as of1, open('out2.txt','w') as of2:
    outf = of1
    for line in inf:
        if 'string pattern' in line:
            outf = of2
            continue  # prevent output of the line with "string pattern" 
        outf.write(line)

将处理大文件,因为它逐行工作。假设string pattern在输入文件中只出现一次。如果整个文件可以放入内存,我最喜欢这种str.partition()方法(这可能不是问题)

使用with确保文件在您完成或遇到异常时自动关闭。

于 2012-06-13T18:28:04.173 回答
2

一个天真的例子(不会像 Sven 那样将文件加载到内存中):

with open('file', 'r') as r:
    with open('file1', 'w') as f:
        for line in r:
            if line == 'string pattern\n':
                break
            f.write(line)
    with open('file2', 'w') as f:
        for line in r:
            f.write(line)

这假设'string pattern'在输入文件中发生一次。

如果模式不是固定字符串,则可以使用该re模块。

于 2012-06-13T18:23:32.867 回答
2

一个更有效的答案,它将处理大文件并消耗有限的内存..

inp = open('inputfile')
out = open('outfile1', 'w')
for line in inp:
  if line == "Sentinel text\n":
    out.close()
    out = open('outfile2', 'w')
  else:
    out.write(line)
out.close()
inp.close()
于 2012-06-13T18:24:45.087 回答
2

不超过三行:

with open('infile') as fp, open('of1','w') as of1, open('of2','w') as of2:
    of1.writelines(iter(fp.readline, sentinel))
    of2.writelines(fp)
于 2012-06-13T22:09:09.840 回答
1

你需要类似的东西:

def test_pattern(x):
    if x.startswith('abc'): # replace this with some exact test
        return True
    return False

found = False
out = open('outfile1', 'w')
for line in open('inputfile'):
    if not found and test_pattern(line):
        found = True
        out.close()
        out = open('outfile2', 'w')
    out.write(line)
out.close()

用适用于您的模式的测试替换该行(如有必要,使用来自 re 的模式匹配,但任何找到分隔线的东西都可以)。

于 2012-06-13T18:26:28.143 回答