在Python中打印多个文件的特定行

时间:2017-02-15 02:38:58

标签: python python-3.x enumerate readlines

我有30个文本文件,每个文件有30行。 出于某种原因,我需要编写一个打开文件1的脚本,打印文件1的第1行,关闭它,打开文件2,打印文件2的第2行,关闭它,依此类推。我试过这个:

import glob

files = glob.glob('/Users/path/to/*/files.txt')             
for file in files:
    i = 0
    while i < 30:
        with open(file,'r') as f:
            for index, line in enumerate(f):
                if index == i:
                    print(line)
                    i += 1
                    f.close()
            continue 

显然,我收到了以下错误:

ValueError:关闭文件的I / O操作。

因为f.close()的事情。如何在只读取所需的行之后从文件移动到下一个文件?

4 个答案:

答案 0 :(得分:6)

首先,回答问题,如评论中所述,您的主要问题是您关闭文件然后尝试继续迭代它。有罪的代码:

        for index, line in enumerate(f): # <-- Reads
            if index == i:
                print(line)
                i += 1
                f.close()                # <-- Closes when you get a hit
                                         # But loop is not terminated, so you'll loop again

最简单的解决方法是仅break而不是显式关闭,因为您的with语句已经保证在退出块时确定性关闭:

        for index, line in enumerate(f):
            if index == i:
                print(line)
                i += 1
                break

但是因为这很有趣,所以完成同样的任务需要大量清理代码:

import glob
from itertools import islice

# May as well use iglob since we'll stop processing at 30 files anyway    
files = glob.iglob('/Users/path/to/*/files.txt')

# Stop after no more than 30 files, use enumerate to track file num
for i, file in enumerate(islice(files, 30)):
    with open(file,'r') as f:
        # Skip the first i lines of the file, then print the next line
        print(next(islice(f, i, None)))

答案 1 :(得分:2)

您可以使用linecache模块获取所需的线路并为您节省很多麻烦:

import glob
import linecache

line = 1
for file in glob.glob('/Users/path/to/*/files.txt'):
    print(linecache.getline(file, line))
    line += 1
    if line > 30:  # if you really need to limit it to only 30
        break

答案 2 :(得分:0)

我觉得这样的事情就是你想要的:

import glob

files = glob.glob('/Users/path/to/*/files.txt')             
for file in files:
    i = 0
    while i < 30:
        with open(file,'r') as f:
            for index, line in enumerate(f):
                if index == i:
                    print(line)
                    i += 1
                    break
        f.close()

目前,您正在for循环中间关闭文件,然后尝试再次读取它。因此,如果您只在关闭for循环后关闭文件,那么它应该没问题。

答案 3 :(得分:0)

将您的工作分成更简单的步骤,直到最后一步是微不足道的。使用功能。

请记住,文件对象可用作一系列行。

def nth(n, sequence):
  for position, item in enumerate(sequence):
    if position == n:
      return item
  return None  # if the sequence ended before position n

def printNthLines(glob_pattern)
  # Note: sort file names; glob guarantees no order.
  filenames = sorted(glob.glob(glob_pattern))
  for position, filename in enumerate(filenames):
    with open(filename) as f:
      line = nth(position, f)  # Pick the n-th line.
      if line is not None:
        print(line)
      # IDK what to do if there's no n-th line in n-th file

printNthLines('path/to/*/file.txt')

显然我们将第n个文件扫描到第n行,但这是不可避免的,没有办法直接进入明文文件中的第n行。