【问题标题】:python | move files of certain type from input/source folder to output/destination folder preserving the folder structure蟒蛇 |将特定类型的文件从输入/源文件夹移动到输出/目标文件夹,保留文件夹结构
【发布时间】:2021-10-13 06:27:56
【问题描述】:

我想将输入文件夹及其子目录中的某种类型的文件移动到输出文件夹,但保留输入文件夹中的文件夹结构。

换种说法: 名为“input”的文件夹及其子目录中的所有 PNG 文件都应移至“output”文件夹,包括其父目录结构。

输入文件夹的结构:

+ input
|   |+ input_1.png
|   |+ input_2.png
|   |+ input_3.png
|   |+ input_4.jpg
|   |+ input_5.jpg
|   |+ input_6.jpg
|   |+ subfolder_1
|         |+ 1_1.png
|         |+ 1_2.png
|         |+ 1_3.png
|         |+ 1_4.jpg
|         |+ 1_5.jpg
|         |+ 1_6.jpg
|   |+ subfolder_2
|         |+ 2_1.png
|         |+ 2_2.png
|         |+ 2_3.png
|         |+ 2_4.jpg
|         |+ 2_5.jpg
|         |+ 2_6.jpg
|         |+ subfolder_2_1
|               |+ 2_1_1.png
|               |+ 2_1_2.png
|               |+ 2_1_3.jpg
|               |+ 2_1_4.jpg

目标是:

+ input
|   |+ input_4.jpg
|   |+ input_5.jpg
|   |+ input_6.jpg
|   |+ subfolder_1
|         |+ 1_4.jpg
|         |+ 1_5.jpg
|         |+ 1_6.jpg
|   |+ subfolder_2
|         |+ 2_4.jpg
|         |+ 2_5.jpg
|         |+ 2_6.jpg
|         |+ subfolder_2_1
|               |+ 2_1_3.jpg
|               |+ 2_1_4.jpg
+ output
|   |+ input_1.png
|   |+ input_2.png
|   |+ input_3.png
|   |+ subfolder_1
|         |+ 1_1.png
|         |+ 1_2.png
|         |+ 1_3.png
|   |+ subfolder_2
|         |+ 2_1.png
|         |+ 2_2.png
|         |+ 2_3.png
|         |+ subfolder_2_1
|               |+ 2_1_1.png
|               |+ 2_1_2.png

这是我目前所拥有的:

import os
import shutil

input_folder_name = "input"
input_path = os.path.join(os.getcwd(),input_folder_name)
output_folder_name = "output"
output_path = os.path.join(os.getcwd(),output_folder_name)

for root, dirs, files in os.walk(input_path):
    for file in files:
        if file.endswith(".png"):
            file_source_path = os.path.join(root, file)
            file_output_path = file_source_path.replace(input_folder_name,output_folder_name)
            print("input:",file_source_path)
            print("output:",file_output_path)
            shutil.move(file_source_path,file_output_path)

直接在“输入”文件夹中的文件被移动,但不幸的是,一旦必须移动子文件夹的第一个文件,就会显示错误消息。 错误消息说,目标文件不存在,这当然是真的,因为应该使用 shutil.move() 创建。

有人知道它为什么不工作吗? 每一个提示都表示赞赏。

谢谢。 :)

【问题讨论】:

    标签: python file directory move


    【解决方案1】:

    pathlib 模块有一些有用的工具。如果将文件夹转换为 pathlib.Path 对象,则可以使用 relativeto 函数获取相对于 input 文件夹的路径。之后,只需使用output路径的join函数即可获取新路径。

    Path('output').join(Path(file).relativeto('input'))
    

    【讨论】:

    • 感谢您的提示。由于我对 Python 很陌生,因此我将仔细研究 pathlib 模块。同时,我不明白为什么上面的脚本不起作用。 shutil.move 之前的两个打印行给了我正确的文件路径。它仍然不起作用。 print("input:",file_source_path) # shows the absolute path of the file which should be movedprint("output:",file_output_path) # shows the absolute path of the new file path, which the file should have after moving 那不应该工作吗? (我知道不是,但我不知道为什么。)
    • 进一步研究表明,您使用 shutil.move 的方式存在问题。有关详细信息,请参阅我的其他答案。
    【解决方案2】:

    在您的解决方案中,您使用os.walk 遍历树中的每个文件,从文件夹开始,然后是这些文件夹中的文件。但是,shutil.move 函数将一次性移动文件夹及其内容。在您当前的解决方案中,当os.walk 获取文件时,它们已不再存在,因为它们拥有的文件夹已被移动。

    更好的方法是使用os.listdir 来获取直接子级,然后移动它们。

    for folder in os.listdir(input_path):
        file_source_path = os.path.join(input_path, folder)
        file_output_path = os.path.join(output_path, folder)
        print("input: %s\noutput: %s:", file_source_path, file_output_path)
        if os.path.isdir(file_source_path):
            shutil.move(file_source_path, file_output_path)
        else:
            os.rename(file_source_path, file_output_path)
    

    【讨论】:

    • 啊!现在我懂了。我会尝试。感谢您的快速帮助!
    猜你喜欢
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 2022-08-21
    • 2017-03-31
    • 2019-06-20
    • 1970-01-01
    相关资源
    最近更新 更多