1

私はこのスクリプトを持っていますが、間違いなく欠陥があります:

import fnmatch, os, sys
def findit (rootdir, find, pattern):
    for folder, dirs, files in os.walk(rootdir):
        print (folder)
    for filename in fnmatch.filter(files,pattern):          
        with open(filename) as f:
            s = f.read()
            f.close()
            if find in s :                  
                print(filename)

findit(sys.argv[1], sys.argv[2], sys.argv[3])

実行すると が得られErrno2, no such file or directoryます。しかし、ファイルは存在します。たとえば、次のように実行すると、findit.py c:\python "folder" *.py「フォルダー」という単語を含むすべての *.py ファイルが一覧表示され、問題なく動作します。しかし、もし私が行くならfindit.py c:\php\projects1 "include" *.php

私が得た例として[Errno2] no such file or directory: 'About.php'(たとえば)。しかし、About.php は存在します。それが何をしているのか、何が間違っているのかわかりません。

4

2 に答える 2

2

の例をos.walk見ると、すべてがそうであることがわかりますos.path.join(root, name)。あなたもそうする必要があります。

なんで?ドキュメントからの引用:

filenamesdirpath 内のディレクトリ以外のファイルの名前のリストです。リスト内の名前にはパス コンポーネントが含まれていないことに注意してください。dirpath 内のファイルまたはディレクトリへのフル パス (top で始まる) を取得するには、 を実行しますos.path.join(dirpath, name)

ファイル名をパスとして使用すると、現在の作業ディレクトリで同じ名前のファイルが検索されます。そのようなファイルがない場合は、FileNotFoundError. そのようなファイルがある場合、間違ったファイルを開いて読み取ることになります。たまたま現在の作業ディレクトリ内を見ている場合にのみ機能します。


コードには別の大きな問題もあります。os.walkディレクトリ ツリーを再帰的にたどって、指定されたtopディレクトリ、または のサブディレクトリtop、または…のサブディレクトリ内のすべてのファイルを検索し、ディレクトリごとに 1 回生成します。しかし、あなたはそれで何も役に立ちません(フォルダを印刷することを除いて)。代わりに、終了するまで待ってfilesから、たまたま最後に到達したディレクトリからを使用します。

ディレクトリ内のファイルのフラットなリストを直接取得したいだけの場合はos.listdir、 ではなくを使用してくださいos.walk。(またはglob.glob、すべてを明示的にリストしてから でフィルタリングする代わりに使用することもできますfnmatch。)

一方、ツリーをたどりたい場合は、2 番目forのループを最初のループ内に移動する必要があります。


また、小さな問題もあります。f.close()内で呼び出すとwith open(…) as f:f2 回閉じられます。これは完全に無害であることが保証されています (少なくとも 3.x を含む 2.5+ では) が、それでも悪い考えです。


まとめると、コードの動作バージョンは次のとおりです。

def findit (rootdir, find, pattern):
    for folder, dirs, files in os.walk(rootdir):
        print (folder)
        for filename in fnmatch.filter(files,pattern):
            pathname = os.path.join(folder, filename)
            with open(pathname) as f:
                s = f.read()
                if find in s:
                    print(pathname)
于 2013-04-03T23:43:10.097 に答える
1

相対ファイル名を使用しています。ただし、現在のディレクトリにはファイルが含まれていません。とにかくそこを検索したくありません。os.path.join(folder, filename) を使用して絶対パスを作成します。

于 2013-04-03T23:36:15.160 に答える