python: 从所有子目录中收集一个扩展名的文件

python: collect files with one extention from all sub-dir

我正在尝试收集包含所有子目录的所有文件并移动到另一个目录

使用的代码

#collects all mp3 files from folders to a new folder
import os
from pathlib import Path
import shutil


#run once
path = os.getcwd()
os.mkdir("empetrishki")
empetrishki = path + "/empetrishki" #destination dir
print(path)
print(empetrishki)

#recursive collection
for root, dirs, files in os.walk(path, topdown=True, onerror=None, followlinks=True):
    for name in files:
        filePath = Path(name)
        if filePath.suffix.lower() == ".mp3":
            print(filePath)
            os.path.join
            filePath.rename(empetrishki.joinpath(filePath))

我在移动文件的最后一行时遇到问题:filePath.rename()shutil.movejoinpath() 都不适合我。也许那是因为我正在尝试更改元组中的元素 - os.walk

的输出

类似的代码适用于 os.scandir 但这只会收集当前目录中的文件

我该如何解决,谢谢!

for root, dirs, files in os.walk(path, topdown=True, onerror=None, followlinks=True):
    if root == empetrishki:
        continue  # skip the destination dir
    for name in files:
        basename, extension = os.path.splitext(name)
        if extension.lower() == ".mp3":
            oldpath = os.path.join(root, name)
            newpath = os.path.join(empetrishki, name)
            print(oldpath)
            shutil.move(oldpath, newpath)

这就是我的建议。您的代码在当前目录 运行 中,文件在路径 os.path.join(root, name) 中,您需要为移动函数提供这样的路径。

此外,我还建议使用os.path.splitext提取文件扩展名。更像蟒蛇。而且你可能想跳过扫描你的目标目录。

如果您使用 pathlib.Path(name) 这并不意味着存在名为 name 的东西。因此,您确实需要注意您拥有完整路径或相对路径,并且您需要确保解决这些问题。特别是我注意到你没有改变你的工作目录并且有这样一行:

filePath = Path(name)

这意味着当您沿着目录向下走时,您的工作目录可能不会改变。您应该从根目录和名称开始创建路径,解析以便知道完整路径也是一个好主意。

filePath = Path(root).joinpath(name).resolve()

您也可以将 Path(root) 放在内部循环之外。现在您有了从“/home/”到文件名的绝对路径。因此,您应该能够使用 .rename() 重命名,例如:

filePath.rename(x.parent.joinpath(newname))
#Or to another directory
filePath.rename(other_dir.joinpath(newname))

总计:

from pathlib import os, Path

empetrishki = Path.cwd().joinpath("empetrishki").resolve()
for root, dirs, files in os.walk(path, topdown=True, onerror=None, followlinks=True):
    root = Path(root).resolve()
    for name in files:
        file = root.joinpath(name)
        if file.suffix.lower() == ".mp3":
            file.rename(empetrishki.joinpath(file.name))