Python - 如何使用seek()向后导航文本文件多行?

时间:2018-02-06 20:48:44

标签: python python-2.7

我想要做的是匹配文本文件中的短语,然后打印该行(这很好)。然后我需要将光标向上移动4行,这样我就可以在该行中进行另一个匹配,但我不能让seek()方法从已匹配的行向上移动4行,以便我可以进行另一个正则表达式搜索。所有我可以用seek()做的就是从文件的最末端开始搜索。它似乎不允许我从匹配的行中寻找(105,1)。

###这是test.txt的示例
This is 1st line
This is 2nd line # Needs to seek() to this line from the 6th line. This needs to be dynamic as it wont always be 4 lines.
This is 3rd line
This is 4th line
This is 5th line
This is 6st line # Matches this line, now need to move it up 4 lines to the "2nd line"
This is 7 line
This is 8 line
This is 9 line
This is 10 line
def Findmatch():
    file = open("test.txt", "r")
    print file.tell() # shows 0 which is the beginning of the file
    string = file.readlines()

    for line in string:
        if "This is 6th line" in line:
            print line
            print file.tell() # shows 171 which is the end of the file. I need for it to be on the line that matches my search which should be around 108. seek() only lets me search from end or beginning of file, but not from the line that was matched.

Findmatch() 

1 个答案:

答案 0 :(得分:2)

由于您已使用file.readlines()一次将所有内容全部读入内存。 tell()方法确实正确地指向了结尾,并且您已经拥有数组中的所有行。如果您仍然想要,则必须逐行读取文件并在文件中记录每行开头的位置,以便您可以返回四行。

针对您描述的问题。您可以先找到第一个匹配的行的索引,然后从列表切片开始执行第二个操作。之前的四个项目。

这是一个非常粗略的例子(return None并不是真正需要的,它只是为了冗长,明确说明意图/预期的行为;提出异常也可能同样如此根据整体计划的要求而改变:

def relevant(value, lines):
    found = False
    for (idx, line) in enumerate(lines):
        if value in line:
            found = True
            break # Stop iterating, last idx is a match.
    if found is True:
        idx = idx - 4
        if idx < 0:
            idx = 0  # Just return all lines up to now? Or was that broken input and fail?
        return lines[idx:]
    else:
        return None

with open("test.txt") as in_file:
    lines = in_file.readlines()

print(''.join(relevant("This is 6th line", lines)))

请注意:名称列表string有点令人困惑(人们可能希望str在那里),请使用lines或其他内容)和它也是不可取的(特别是因为你指示使用2.7)来分配你已经用于内置函数的变量名,比如file。例如,使用in_file

编辑:根据评论中的要求,只是一个打印示例,并行添加它,因为前者似乎可能对进一步扩展更有用。 :) ...

def print_relevant(value, lines):
    found = False
    for (idx, line) in enumerate(lines):
        if value in line:
            found = True
            print(line.rstrip('\n'))
            break # Stop iterating, last idx is a match.
    if found is True:
        idx = idx - 4
        if idx < 0:
            idx = 0  # Just return all lines up to now? Or was that broken input and fail?
        print(lines[idx].rstrip('\n'))

with open("test.txt") as in_file:
    lines = in_file.readlines()

print_relevant("This is 6th line", lines)

请注意,由于使用尾随换行符读入行,print会在打印前添加其自己的一行rstrip&#39;请注意它。