python os.walk 特定のレベルまで [重複] 質問する

python os.walk 特定のレベルまで [重複] 質問する

基本的なコードを使用してフォルダーを読み取り、フォルダー内のファイルの数を確認するプログラムを構築したいと考えています。現在、次のように実行しています。

import os

folders = ['Y:\\path1', 'Y:\\path2', 'Y:\\path3']
for stuff in folders:
    for root, dirs, files in os.walk(stuff, topdown=True):
        print("there are", len(files), "files in", root)

これは、「メイン」フォルダ内に複数のフォルダがあるまではうまく機能しますが、フォルダ/ファイルの管理が不十分なために、長くてジャンクなファイル リストが返される可能性があります。そのため、最大で 2 番目のレベルまでしか移動しないようにします。例:

Main Folder
---file_i_want
---file_i_want
---Sub_Folder
------file_i_want <--*
------file_i want <--*
------Sub_Folder_2
---------file_i_dont_want
---------file_i_dont_want

私は最初のレベルにのみ移動する方法を知っておりbreakdel dirs[:]から取得しましたこの郵便受けそしてこの投稿も

import os
import pandas as pd

folders = ['Y:\\path1', 'Y:\\path2', 'Y:\\path3']
for stuff in folders:
    for root, dirs, files in os.walk(stuff, topdown=True):
        print("there are", len(files), "files in", root)
        del dirs[:] # or a break here. does the same thing.

しかし、いくら検索しても、2 層の深さまで進む方法が見つかりません。他の投稿を理解していないだけかもしれません。私は、このようなことを考えていましたdel dirs[:2]が、役に立ちませんでした。誰か、これを実現する方法を教えてくれたり、説明してくれたりしませんか?

ベストアンサー1

次のようにすることができます:

depth = 2

# [1] abspath() already acts as normpath() to remove trailing os.sep
#, and we need ensures trailing os.sep not exists to make slicing accurate. 
# [2] abspath() also make /../ and ////, "." get resolved even though os.walk can returns it literally.
# [3] expanduser() expands ~
# [4] expandvars() expands $HOME
# WARN: Don't use [3] expanduser and [4] expandvars if stuff contains arbitrary string out of your control.
#stuff = os.path.expanduser(os.path.expandvars(stuff)) # if trusted source
stuff = os.path.abspath(stuff)

for root,dirs,files in os.walk(stuff):
    if root[len(stuff):].count(os.sep) < depth:
        for f in files:
            print(os.path.join(root,f))

キーは次のとおりです:if root[len(stuff):].count(os.sep) < depth

stuffから削除されるrootため、結果は に相対的になりますstuff。ファイル区切り文字の数を数えるだけです。

depth はfindLinux にあるコマンドのように動作します。つまり、-maxdepth 0何もせず、-maxdepth 1最初のレベルのファイルのみをスキャンし、-maxdepth 2サブディレクトリに含まれるファイルをスキャンすることを意味します。

もちろん、ファイル構造全体をスキャンしますが、非常に深いものでない限りは機能します。

別の解決策としては、再帰レベルを最大にして再帰的に(ディレクトリ チェック付きで)のみ使用することですos.listdirが、必要がない場合は少し扱いに​​くくなります。それほど難しくはないので、実装例を 1 つ示します。

def scanrec(root):
    rval = []

    def do_scan(start_dir,output,depth=0):
        for f in os.listdir(start_dir):
            ff = os.path.join(start_dir,f)
            if os.path.isdir(ff):
                if depth<2:
                    do_scan(ff,output,depth+1)
            else:
                output.append(ff)

    do_scan(root,rval,0)
    return rval

print(scanrec(stuff))  # prints the list of files not below 2 deep

注意:os.listdirおよび はos.path.isfile2 回の呼び出しを実行するためstat、最適ではありません。Python 3.5 では、 を使用すると、os.scandirこの二重呼び出しを回避できます。

おすすめ記事