如何从文件中的某个位置提取一定数量的行

时间:2013-04-08 10:48:07

标签: python

我有一个看起来像这样的输入文件:

#nP 4
#mP 0.0262
#mH     10
#HP various info:
14  H   0.026
19  P   0.054
20  H   0.012
512 H   0.005
#xP
#kP
99
89
90

我想从第5行开始提取4行(因为第一行中的np = 4),因此输出将如下所示:

14  H   0.026
19  P   0.054
20  H   0.012
512 H   0.005

我试过这个:

import sys

head = sys.stdin.readline()
head = head.strip()
head = head.split('\t')
cntHetPos = int(head[1])
if "#HP" in sys.stdin.readlines():
  lines = sys.stdin.readlines()[0:cntHetPos]
  print lines

但它不会打印出行,也不会给出错误消息。我的建议基于我在此处找到的先前答案:Read file from line 2 or skip header row 想法?

4 个答案:

答案 0 :(得分:2)

readlines()会在您第一次调用它时返回所有行的列表,但第二次,它是空的,因为所有行都已被读取和使用。将它们存储在变量中:

lines = sys.stdin.readlines()

将它置于顶部,因为您也可以使用它来阅读head变量:

head = lines[0]

另一个问题是你需要遍历所有行来查找#HP令牌,并且需要跟踪行号以便正确切片列表:

for i, line in enumerate(lines):
  if "#HP" in line:
    lines = lines[i+1 : i+1+cntHetPos]

最后,如果你想打印行而不是格式化列表,你需要加入它们(注意行尾字符已经在那里):

    print ''.join(lines),

而且,为了更好地衡量,我们可以在找到正确的行后立即停止,因此我们break就在print之后。

总结一下:

import sys

lines = sys.stdin.readlines()
head = lines[0]
head = head.strip()
head = head.split('\t')
cntHetPos = int(head[1])
for i, line in enumerate(lines):
  if "#HP" in line:
    lines = lines[i+1 : i+1+cntHetPos]
    print ''.join(lines),
    break

答案 1 :(得分:0)

这是一个非常难看的匹配模式,但它可能符合您的需求;

/#nP.*?#HP.*?$.*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+)/gsm

它会将您要抓取的4条线的结果分组并将它们分组。您甚至可以对结果进行分组,以便您立即单独获取14 H 0.026。喜欢的东西;

(\d+) +(\w) +([\d\.]+)

示例

import re

string = '''#nP 4
#mP 0.0262
#mH     10
#HP various info:
14  H   0.026
19  P   0.054
20  H   0.012
512 H   0.005'''

result = re.findall('#nP.*?#HP.*?$.*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+)', string, re.S | re.M)

print(result)

<强>输出

[('14  H   0.026', '19  P   0.054', '20  H   0.012', '512 H   0.005')]

答案 2 :(得分:0)

也许是这样的:

from itertools import islice

with open('yourfile') as fin:
    count = int(next(fin).split()[1])
    non_comments = (line for line in fin if not line.startswith('#'))
    print list(islice(non_comments, None, count))
    # ['14  H   0.026\n', '19  P   0.054\n', '20  H   0.012\n', '512 H   0.005\n']

答案 3 :(得分:0)

linecache module专为从文件中有效读取行而定制:

  

linecache module允许任何人从任何文件获取任何行,而   试图在内部优化,使用缓存,常见的情况   从单个文件中读取许多行。这被使用了   回溯模块,用于检索包含在中的源行   格式化的追溯。

假设文本文件名为blah,文件数据从第五行开始:

#!/usr/bin/python   

import linecache

starting_line_number = 5   
number_of_lines      = int(linecache.getline('blah',1).split()[1])
for line_num in range(starting_line_number, starting_line_number+number_of_lines):
    print linecache.getline('blah',line_num),