仅枚举具有特定名称的文件夹中的文件

时间:2014-11-11 19:09:30

标签: python python-2.7

我有一个文件夹结构和这样的文件:

 - doe-john
   - inbox
      - 1.
      - 2.
      - 3.
   - sent
      - 1.
      - 2.
      - 3.
   - notes
      - 1.
      - 2.
      - 3.
   - contacts
      - 1.
      - 2.
      - 3.
 - doe-jane
   - inbox
      - 1.
      - 2.
      - 3.
   - sent
      - 1.
      - 2.
      - 3.
   - notes
      - 1.
      - 2.
      - 3.
   - contacts
      - 1.
      - 2.
      - 3.

我只想枚举每个主文件夹中inboxsent个文件夹中的文件。我知道如何枚举所有文件:

for root, dirs, files in os.walk(top_level_folder):
    for fn in files:
        with open(os.path.join(root, fn), 'r') as f:
            pass  # do something

我认为我会这样做,但我不太确定如何正确地做到这一点:

for root, dirs, files in os.walk(top_level_folder):
    for dir in dirs:
        if dir.lower() == "inbox" or dir.lower() == "sent":
            for fn in files:
                with open(os.path.join(root, fn), 'r') as f:
                    pass  # do something

但这仍然只是列举了所有文件。如何枚举具有指定文件夹名称的文件夹中的文件?

2 个答案:

答案 0 :(得分:3)

您让rootdirs感到困惑。 root是"当前目录"在每个级别; dirs在此级别可见的目录列表

您当前的代码处理每个目录中的所有文件,每个可见子目录一次。您想要的是查看当前目录是inbox还是sent,然后才进行处理。

for root, dirs, files in os.walk(top_level_folder):
    if root.lower().endswith("inbox") or root.lower().endswith("sent"):
        for fn in files:
            with open(os.path.join(root, fn), 'r') as f:
                pass  # do something

您还可以在topdown=True来电中设置walk,然后修改要导入的子目录。

for root, dirs, files in os.walk(top_level_folder, topdown=True):
    if root != top_level_folder:
        # only recurse into level 3+ directories with the desired names
        dirs[:] = [d for d in dirs if d in ['inbox', 'sent']]
    if root.lower().endswith("inbox") or root.lower().endswith("sent"):
        for fn in files:
            with open(os.path.join(root, fn), 'r') as f:
                pass  # do something

但是,我觉得这个选项有点难看(特别是因为你需要在顶级特殊情况下避免跳过/doe-john等)。在您的特定情况下,由于您只想查看两个目录并且它们只有一个级别,我根本不会使用walk

for person in os.listdir(top_level_folder):
    inbox = os.path.join(top_level_folder, person, 'inbox')
    sent = os.path.join(top_level_folder, person, 'sent')

    for file in os.listdir(inbox):
        pass # Do something

    for file in os.listdir(sent):
        pass # Do something

答案 1 :(得分:1)

如果您使用dirs选项,则可以修改从os.walk()返回的topdown=True。根据{{​​3}}:

  

topdown True时,调用者可以就地修改 dirnames 列表(可能使用del或切片分配),并且walk()只会递归到名称保留在 dirnames 中的子目录中;这可用于修剪搜索,强制执行特定的访问顺序,甚至可以通知walk()有关调用者在再次恢复walk()之前创建或重命名的目录。当 topdown False时修改 dirnames 无效,因为在自下而上模式下, dirnames 中的目录是在之前生成的dirpath 本身已生成。