Pythonでディレクトリを反復処理する


157

特定のディレクトリのサブディレクトリを繰り返し処理して、ファイルを検索する必要があります。ファイルを取得した場合、そのファイルを開いて内容を変更し、独自の行に置き換える必要があります。

私はこれを試しました:

import os

rootdir ='C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        f=open(file,'r')
        lines=f.readlines()
        f.close()
        f=open(file,'w')
        for line in lines:
            newline = "No you are not"
            f.write(newline)
        f.close()

エラーが発生します。何が悪いのですか?


12
「エラー」-特にエラーはありますか?
Daniel Roseman 2013年

1
ウォークスルーが意図したとおりに機能するようになったら、ファイル/ディレクトリで何をしたいかについて少し説明していただけますか?エラーの詳細もお知らせください。
ChrisProsser 2013年

1
私が得るエラーメッセージは、ファイルcool.txtが見つからないということです。私のテストフォルダーにはsrcと呼ばれる別のフォルダーがあり、srcフォルダーにはmainと呼ばれる別のフォルダーがあり、このフォルダーにはcool.txt
Wolf

4
質問にエラーを書き込むことができますか?それを見つけるためにコメントを読まなければならないのは面倒で不必要なだけです。
チャーリーパーカー、

1
1年以上後、エラーの投稿をリクエストしているとは思えません。@ウルフ
チャーリーパーカー

回答:


300

ディレクトリを実際にウォークするのは、コーディングしたとおりです。内部ループの内容を単純なprintステートメントに置き換えると、各ファイルが見つかったことがわかります。

import os
rootdir = 'C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        print os.path.join(subdir, file)

上記を実行しても引き続きエラーが発生する場合は、エラーメッセージを入力してください。


Python3用に更新

import os
rootdir = 'C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        print(os.path.join(subdir, file))

1
C:/ Users / sid / Desktop / test \ src \ app / cool.txt C:/ Users / sid / Desktop / test \ src \ app / woohoo.txtコードのオープンステートメントで、ファイルへの絶対パスを指定します。import os rootdir = 'C:/ Users / spemmara / Desktop / test / src / app /' for subdir、dirs、files in os.walk(rootdir):for file in files:f = open(subdir + '/' + file 、 'r')lines = f.readlines()f.close()f = open(subdir + '/' + file、 'w')for line in lines:newline = "hey i know" f.write(newline) f.close()ありがとうございます。その解決
オオカミ

3
こんにちは!Python 3の「印刷」には括弧が必要であり、そうでない場合は構文エラーが返されることに注意してください。お役に立てれば!
Tommaso Di Noto

14

サブディレクトリのすべてのファイルを返す別の方法は、Python 3.4で導入されpathlibモジュールを使用することです。これは、ファイルシステムパスを処理するオブジェクト指向のアプローチを提供します(Pathlibは、PyPiのpathlib2モジュールを介し Python 2.7でも利用できます)。

from pathlib import Path

rootdir = Path('C:/Users/sid/Desktop/test')
# Return a list of regular files only, not directories
file_list = [f for f in rootdir.glob('**/*') if f.is_file()]

# For absolute paths instead of relative the current dir
file_list = [f for f in rootdir.resolve().glob('**/*') if f.is_file()]

Python 3.5以降、globモジュールは再帰的なファイル検索もサポートしています。

import os
from glob import iglob

rootdir_glob = 'C:/Users/sid/Desktop/test/**/*' # Note the added asterisks
# This will return absolute paths
file_list = [f for f in iglob('**/*', recursive=True) if os.path.isfile(f)]

file_list上記のアプローチのいずれかから、ネストされたループを必要とせずに反復処理することができます。

for f in file_list:
    print(f) # Replace with desired operations

1
ここでPython 3.6に望ましいのは何ですか?
PhoenixDev 2017年

@PhoenixDevあるアプローチが他のアプローチよりも一般的に推奨されていることを聞いたことがありません。pathlib主にオブジェクト指向のメソッド構文が好きなので、私は自分自身を使用することを好みます。パスライブラリは文字列ではなく特定のパスクラスを返し、使用可能な関数はライブラリ間で異なります(例:os.path.expanduser('~')Path.home())。ドキュメントを参照して、どちらのアプローチが望ましいかを確認してください。
joelostblom 2017年

**globパターンを追加する代わりに、を使用できますrglob
ジョージー

12

のとして2020年glob.iglob(path/**, recursive=True)ほとんどのようですニシキヘビソリューション、すなわち:

import glob, os

for filename in glob.iglob('/pardadox-music/**', recursive=True):
    if os.path.isfile(filename): # filter dirs
        print(filename)

出力:

/pardadox-music/modules/her1.mod
/pardadox-music/modules/her2.mod
...

注:
1- glob.iglob

glob.iglob(pathname, recursive=False)

glob()実際にすべてを同時に格納しない場合と同じ値を生成するイテレータを返します。

2 -は再帰的である場合はTrue、パターンは'**'任意のファイルと0個以上一致するdirectoriesとはsubdirectories

3-ディレクトリに次で始まるファイルが含まれる場合、  .デフォルトでは一致しません。たとえば、card.gif およびを含むディレクトリについて考え  .card.gifます。

>>> import glob
>>> glob.glob('*.gif') ['card.gif'] 
>>> glob.glob('.c*')['.card.gif']

4-を使用することもできますrglob(pattern)。これは、指定された相対パターンの前に追加された呼び出しglob() と同じ  **/です。


1
このpythonicソリューションは隠しファイル(別名dotfiles)をリストしませんが、受け入れられたファイルはリストします。
アシュラムン

@ashrasmunあなたが言及したことは、docs.python.org
/
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.