使用python将特定行从一个文件写入另一个文件

使用python将特定行从一个文件写入另一个文件,python,Python,我有大约200个短文本文件(50kb),它们都有相似的格式。我想在每个文件中找到一行,其中包含某个字符串,然后将该行加上接下来的三行(但不是文件中的其余行)写入另一个文本文件。为了做到这一点,我尝试自学python,并编写了一个非常简单和粗糙的小脚本来尝试这一点。我正在使用版本2.6.5,并从Mac终端运行脚本: #!/usr/bin/env python f = open('Test.txt') Lines=f.readlines() searchquery = 'am\n' i=0 w

我有大约200个短文本文件(50kb),它们都有相似的格式。我想在每个文件中找到一行,其中包含某个字符串,然后将该行加上接下来的三行(但不是文件中的其余行)写入另一个文本文件。为了做到这一点,我尝试自学python,并编写了一个非常简单和粗糙的小脚本来尝试这一点。我正在使用版本2.6.5,并从Mac终端运行脚本:

#!/usr/bin/env python

f = open('Test.txt')

Lines=f.readlines()
searchquery = 'am\n'
i=0

while i < 500:
    if Lines[i] == searchquery:
        print Lines[i:i+3]
        i = i+1
    else:
        i = i+1
f.close()
而且也不能让它起作用。如果有人能解释我做错了什么,或者就我应该尝试什么提出一些建议,我将非常感激。此外,如果你有任何建议,使搜索更好,我也会感谢这些。我一直在使用一个测试文件,其中我想要查找的字符串是行中唯一的文本,但在我的实际文件中,我需要的字符串仍然在行的开头,但后面跟着一堆其他文本,因此我认为我现在设置的方式也不会真正起作用


谢谢,如果这是一个超级基本的问题,我很抱歉

我认为您的问题在于底部文件的选项卡

您需要从if
行[i]
缩进到
i=i+1
之后,例如:

while i < 500:
    if Lines[i] == searchquery:
        f2.write(Lines[i])
        f2.write(Lines[i+1])
        f2.write(Lines[i+2])
        i = i+1
    else:
        i = i+1
当i<500时:
如果行[i]==搜索查询:
f2.写入(第[i]行)
f2.写入(行[i+1])
f2.写入(第[i+2]行)
i=i+1
其他:
i=i+1

正如@ajon所指出的,我认为您的代码除了缩进之外没有任何根本性的错误。有了固定的缩进,它对我很有效。然而,还有一些改进的机会

1)在Python中,迭代事物的标准方法是使用。当为循环使用
时,您不需要定义循环计数器变量并自己跟踪它们来迭代。相反,你写了这样的东西

for line in lines:
    print line
with open('test.txt') as f:
    f.write('foo')
迭代字符串列表中的所有项并打印它们

2)在大多数情况下,这就是您的
for
循环的外观。然而,在某些情况下,您确实希望跟踪循环计数。您的情况就是这种情况,因为您不仅需要这一行,还需要接下来的三行,因此需要使用计数器进行索引(
lst[i]
)。对于这一点,它将返回一个项目列表及其索引,然后您可以在其上循环

for i, line in enumerate(lines):
    print i
    print line
    print lines[i+7]
如果要像示例中那样手动跟踪循环计数器,有两件事:

3)应将
i=i+1
移出
if
else
块。在这两种情况下都是这样,所以请将其放在
if/else
后面。在您的情况下,
else
块不再执行任何操作,可以消除:

while i < 500:
    if Lines[i] == searchquery:
        f2.write(Lines[i])
        f2.write(Lines[i+1])
        f2.write(Lines[i+2])
    i = i+1
5)可作为一个用于为您关闭文件的工具。上下文管理器是一个相当高级的概念,但是如果已经为您提供了上下文管理器,那么它的使用非常简单。通过做这样的事情

for line in lines:
    print line
with open('test.txt') as f:
    f.write('foo')
该文件将以
f
的形式打开并可供您使用
块访问。离开块后,文件将自动关闭,因此不会忘记关闭文件

在你的情况下,你打开了两个文件。这可以通过使用两个
语句并嵌套它们来实现

with open('one.txt') as f1:
    with open('two.txt') as f2:
        f1.write('foo')
        f2.write('bar')
或者,在Python2.7/Python3.x中,通过将两个上下文管理器嵌套在一个
with
语句中:

    with open('one.txt') as f1, open('two.txt', 'a') as f2:
        f1.write('foo')
        f2.write('bar')
6)根据创建文件的操作系统,行尾不同。在类UNIX平台上,它是
\n
,在OSX之前的Mac使用
\r
,Windows使用
\r\n
。因此,
行[i]==searchquery
将与Mac或Windows行结尾不匹配
file.readline()
可以处理这三种情况,但由于它保留了行末尾的任何行结尾,因此比较将失败。这可以通过使用解决,它将去掉字符串开头和结尾的所有空白,并将不带行尾的搜索模式与以下模式进行比较:

searchquery = 'am'
# ...
            if line.strip() == searchquery:
                # ...
(使用
file.read()
读取文件并使用将是另一种选择。)

但是,由于您提到您的搜索字符串实际上出现在行的开头,因此让我们使用:

7)Python的官方风格指南建议对类使用
CamelCase
,对几乎所有其他内容(变量、函数、属性、方法、模块、包)使用
小写下划线。因此,不要使用
而使用
。与其他观点相比,这无疑是一个次要的观点,但仍然值得及早纠正


因此,考虑到所有这些因素,我会像这样编写您的代码:

f1 = open('Test.txt')
f2 = open('Output.txt', 'a')

Lines=f1.readlines()
searchquery = 'am\n'
i=0

while i < 500:
if Lines[i] == searchquery:
    f2.write(Lines[i])
    f2.write(Lines[i+1])
    f2.write(Lines[i+2])
    i = i+1
else:
    i = i+1
f1.close()
f2.close()
searchquery = 'am'

with open('Test.txt') as f1:
    with open('Output.txt', 'a') as f2:
        lines = f1.readlines()
        for i, line in enumerate(lines):
            if line.startswith(searchquery):
                f2.write(line)
                f2.write(lines[i + 1])
                f2.write(lines[i + 2])

正如@TomK所指出的,所有这些代码都假设如果搜索字符串匹配,那么后面至少有两行。如果您不能依赖该假设,那么使用@poorsod suggered之类的块来处理这种情况是正确的方法。

ajon给出了正确的答案,但只要您寻求指导,您的解决方案就不会利用Python提供的高级构造。那么:

searchquery = 'am\n'

with open('Test.txt') as f1:
  with open(Output.txt, 'a') as f2:

    Lines = f1.readlines()

    try:
      i = Lines.index(searchquery)
      for iline in range(i, i+3):
        f2.write(Lines[iline])
    except:
      print "not in file"
即使发生异常,这两个“with”语句也会在最后自动关闭文件

更好的解决方案是避免一次读取整个文件(谁知道它有多大?),而是使用文件对象上的迭代逐行处理:

  with open('Test.txt') as f1:
    with open(Output.txt, 'a') as f2:
      for line in f1:
        if line == searchquery:
          f2.write(line)
          f2.write(f1.next())
          f2.write(f1.next())

所有这些都假设在目标行之外至少还有两行。

您是否尝试过使用“Output.txt”以外的东西来避免任何与文件系统相关的问题

那么,在诊断这一问题时,是否有一个绝对路径来避免任何不可预见的问题呢

  with open('Test.txt') as f1:
    with open(Output.txt, 'a') as f2:
      for line in f1:
        if line == searchquery:
          f2.write(line)
          f2.write(f1.next())
          f2.write(f1.next())
from itertools import slice

f1 = open('Test.txt')
f2 = open('Output.txt', 'a')

bunch = 500
lines = list(islice(f1, bunch)) 
f2.writelines(lines)

f1.close()
f2.close()