简体   繁体   English

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

[英]Print specific lines of multiple files in Python

I have 30 text files of 30 lines each. 我有30个文本文件,每个30行。 For some reason, I need to write a script that opens file 1, prints line 1 of file 1, closes it, opens file 2, prints line 2 of file 2, closes it, and so on. 出于某种原因,我需要编写一个打开文件1的脚本,打印文件1的第1行,关闭它,打开文件2,打印文件2的第2行,关闭它,依此类推。 I tried this: 我试过这个:

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 

Obviously, I got the following error: 显然,我收到以下错误:

ValueError: I/O operation on closed file. ValueError:关闭文件的I / O操作。

Because of the f.close() thing. 因为f.close()的事情。 How can I do to move from a file to the next one after reading only the desired line? 如何只读取所需的行后,如何从文件移动到下一个文件?

First off, to answer the question, as noted in the comments, your main problem is that you close the file then try to continue iterating it. 首先,回答问题,如评论中所述,您的主要问题是您关闭文件然后尝试继续迭代它。 The guilty code: 有罪的代码:

        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

The simplest fix is to just break instead of explicitly closing, since your with statement already guarantees deterministic closing when the block is exited: 最简单的解决方法是break而不是显式关闭,因为在退出块时, with语句已经保证了确定性关闭:

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

But because this was fun, here's a significantly cleaned up bit of code to accomplish the same task: 但是因为这很有趣,所以这里有一个显着清理的代码来完成相同的任务:

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)))

You can use the linecache module to get the line you need and save yourself a lot of headache: 您可以使用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

I think something like this is what you want: 我觉得这样的事情就是你想要的:

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()

Currently you are closing the file in the middle of the for loop and then trying to read it in again. 目前,您正在for循环中间关闭文件,然后尝试再次读取它。 So if you only close the file once you are out of the for loop it should be ok. 因此,如果您只在关闭for循环后关闭文件,那么它应该没问题。

Split your job into simpler steps, until the final step is trivial. 将您的工作分成更简单的步骤,直到最后一步是微不足道的。 Use functions. 使用功能。

Remember that a file object works as a sequence of lines. 请记住,文件对象用作一系列行。

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')

Obviously we scan n-th file to n-th line, but this is inevitable, there's no way to get directly to n-th line in a plaintext file. 显然我们将第n个文件扫描到第n行,但这是不可避免的,没有办法直接进入明文文件中的第n行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM