2016-06-20 8 views
1

私の目標は、特定のサブディレクトリに含まれるすべてのファイルをzipアーカイブ内にリストすることです。os.listdirジップディレクトリのアナログ

os.listdir(target_dir)FileNotFoundErrorを、そしてzfile.namelist()がすべてのディレクトリのすべてのファイルをリストするだけです。

アイデア?

答えて

1

次のことを試してみてください。

files = list(filter(lambda f: f.startswith("subdir"), zfile.namelist())) 

print(files) 

説明:filterは、ファイル名は「サブディレクトリ」で始まるかどうかをチェックしているlambdazfile.namelist()から供給されたリストをフィルタリングします。

filter関数はリストを返すのではなく、フィルタオブジェクト(ジェネレータ)を返すので、リストに変換する必要があります。

また同じことを行いますが、リストの内包表記を使用して次の行を使用することができます。

files = [f for f in zfile.namelist() if f.startswith("subdir")] 

編集:advance512で指摘したように:「この解決策の問題は、それがまた、サブディレクトリ内のファイルを返すということですあなたがチェックしているサブディレクトリ内にあります。」:

files = [f for f in zfile.namelist() if f.startswith("subdir") and f.count("/") == 1] 

サブサブディレクトリ内のファイルは返されません。

+1

このソリューションの問題は、チェックしているサブディレクトリ内のサブディレクトリにもファイルが返されることです。これがあなたが探しているものなら、それは良い解決策です(私は一般的にラムダと理解を好みますが、機能を求めています)。 – advance512

+0

@ advance512ありがとう、私はそれを考慮しませんでした。私は自分の答えを更新しました。 –

+2

また、regex式を使用して、特定のサブディレクトリのすべてのファイル(≠サブディレクトリ)を取得することもできます:recompile( "^(" + re。エスケープ( "subdir")+ r "\/[^ \ /] *?)$")。match(f)] '。しかし、この場合、 're'モジュールをインポートして使用する必要があります。そのため、私は@SimonKirstenオリジナルの答えをより好む。 –

2

付属のzip_listdir機能を使用することができます。これは少しクイックダーティですが、Unixクローンでは常に動作するはずです。

class MockZipFile(object): 
    fake_file_names = [ 
     "string.pyc", # Top level name 
     "test/__init__.pyc", # Package directory 
     "test/test_support.pyc", # Module test.test_support 
     "test/bogus/__init__.pyc", # Subpackage directory 
     "test/bogus/myfile.pyc" # Submodule test.bogus.myfile 
    ] 

    def namelist(self): 
     return self.fake_file_names 


def zip_listdir(zip_file, target_dir): 

    file_names = zip_file.namelist() 

    if not target_dir.endswith("/"): 
     target_dir += "/" 

    if target_dir == "/": 
     target_dir = "" 

    result = [ file_name 
       for file_name in file_names 
       if file_name.startswith(target_dir) and 
        not "/" in file_name[len(target_dir):] 
       ] 

    return result 

mockZipfile = MockZipFile() 
print zip_listdir(zip_file=mockZipfile, target_dir="test") 
print zip_listdir(zip_file=mockZipfile, target_dir="test/bogus") 
print zip_listdir(zip_file=mockZipfile, target_dir="test/") 
print zip_listdir(zip_file=mockZipfile, target_dir="/") 
print zip_listdir(zip_file=mockZipfile, target_dir="") 
print zip_listdir(zip_file=mockZipfile, target_dir="/asd") 

私はMockZipFileクラスを作成した注意、およびzip_listdir関数の入力としてそれを使用していますが、適切なzipfileオブジェクトはまったく同じに動作するはずですしてください。