我有c++ /Obj-C背景,我刚刚发现Python(写了大约一个小时)。 我正在写一个脚本递归地读取文件夹结构中的文本文件的内容。

我的问题是,我写的代码将只工作于一个文件夹深度。我可以在代码中看到为什么(见#hardcoded path),我只是不知道如何使用Python,因为我对它的经验只是全新的。

Python代码:

import os
import sys

rootdir = sys.argv[1]

for root, subFolders, files in os.walk(rootdir):

    for folder in subFolders:
        outfileName = rootdir + "/" + folder + "/py-outfile.txt" # hardcoded path
        folderOut = open( outfileName, 'w' )
        print "outfileName is " + outfileName

        for file in files:
            filePath = rootdir + '/' + file
            f = open( filePath, 'r' )
            toWrite = f.read()
            print "Writing '" + toWrite + "' to" + filePath
            folderOut.write( toWrite )
            f.close()

        folderOut.close()

当前回答

我认为问题在于你没有处理os的输出。正确的走路。

首先,改变:

filePath = rootdir + '/' + file

to:

filePath = root + '/' + file

Rootdir是固定的起始目录;Root是os.walk返回的目录。

其次,您不需要缩进您的文件处理循环,因为对每个子目录运行这个没有意义。您将获得每个子目录的根集。您不需要手动处理子目录,除非您想对目录本身做一些事情。

其他回答

如果你想要一个给定目录下的所有路径的平面列表(比如find。在壳中):

   files = [ 
       os.path.join(parent, name)
       for (parent, subdirs, files) in os.walk(YOUR_DIRECTORY)
       for name in files + subdirs
   ]

若要只包含基本目录下文件的完整路径,请省略+ subdirs。

如果你使用的是Python 3.5或更高版本,你可以在一行内完成。

import glob

# root_dir needs a trailing slash (i.e. /root/dir/)
for filename in glob.iglob(root_dir + '**/*.txt', recursive=True):
     print(filename)

正如文档中提到的

如果递归为true,模式'**'将匹配任何文件以及零个或多个目录和子目录。

如果你想要每个文件,你可以使用

import glob

for filename in glob.iglob(root_dir + '**/**', recursive=True):
     print(filename)

我认为问题在于你没有处理os的输出。正确的走路。

首先,改变:

filePath = rootdir + '/' + file

to:

filePath = root + '/' + file

Rootdir是固定的起始目录;Root是os.walk返回的目录。

其次,您不需要缩进您的文件处理循环,因为对每个子目录运行这个没有意义。您将获得每个子目录的根集。您不需要手动处理子目录,除非您想对目录本身做一些事情。

我发现下面的方法是最简单的

from glob import glob
import os

files = [f for f in glob('rootdir/**', recursive=True) if os.path.isfile(f)]

使用glob('some/path/**', recursive=True)获取所有文件,但也包括目录名。添加if os.path.isfile(f)条件只过滤现有文件

如果仅仅是文件名还不够,在os.scandir()上实现深度优先搜索是很容易的:

stack = ['.']
files = []
total_size = 0
while stack:
    dirname = stack.pop()
    with os.scandir(dirname) as it:
        for e in it:
            if e.is_dir(): 
                stack.append(e.path)
            else:
                size = e.stat().st_size
                files.append((e.path, size))
                total_size += size

医生是这么说的:

scandir()函数返回目录条目和文件属性信息,为许多常见用例提供了更好的性能。