如何按扩展名重新组织文件,并按类别将其分类到文件夹中?

如何按扩展名重新组织文件,并按类别将其分类到文件夹中?

以下代码由@JacobVlijm 发布。我尝试修改它,因为我想要其他文件夹名称而不是文件扩展名,并且我想将文件扩展名分组到类别中。但是代码不起作用。请参阅错误(我只是 Python 的初学者)

#!/usr/bin/env python3

import os
import subprocess
import shutil

# --------------------------------------------------------
reorg_dir = "/media/ashwin/Work+Entertainment/Untitled Folder"
exclude = () 
remove_emptyfolders = True
# ---------------------------------------------------------

for root, dirs, files in os.walk(reorg_dir):
    for name in files:
        subject = root+"/"+name
        if name.startswith("."):
            extension = ".hidden_files"
        elif not "." in name:
            extension = ".without_extension"
        else:
            extension = name[name.rfind("."):]
        if not extension in exclude:
        if extension==".jpeg" or extension==".jpg" or extension==".JPG" or extension==".png" or extension==".PNG":
        new_dir = reorg_dir+"/Pictures"
        elif extension==".docx" or extension==".doc" or extension==".pdf" or extension==".xlsx" or extension==".ppt" or extension==".pptx":
        new_dir = reorg_dir+"/Documents"
        elif extension==".mp3" or extension==".MP3":
        new_dir = reorg_dir+"/Songs"
        elif extension==".mp4" or extension==".MP4" or extension==".avi" or extension==".AVI":
        new_dir = reorg_dir+"/Videos"
        elif extension==".db" or extension==".DB":
        new_dir = reorg_dir+"/Databases"
        elif extension=="*.*":
        new_dir = reorg_dir+"/Others"

        if not os.path.exists(new_dir):
                os.mkdir(new_dir)
            n = 1; name_orig = name
            while os.path.exists(new_dir+"/"+name):
                name = name_orig
                n = n+1
            newfile = new_dir+"/"+name
            shutil.move(subject, newfile)

def cleanup():
    filelist = []
    for root, dirs, files in os.walk(reorg_dir):
        for name in files:
            filelist.append(root+"/"+name)
    directories = [item[0] for item in os.walk(reorg_dir)]
    for dr in directories:
        matches = [item for item in filelist if dr in item]
        if len(matches) == 0:
            try:
                shutil.rmtree(dr)
            except FileNotFoundError:
                pass

if remove_emptyfolders == True:
    cleanup()

在此代码(由@Jacob Vlijm 发布)中,我尝试向扩展上创建的新目录添加条件。但我收到以下错误:

  File "filemgr.py", line 24
    new_dir = reorg_dir+"/Pictures"
          ^
IndentationError: expected an indented block

请帮帮我。

使用 python3 program.py 时出现更多错误:

ashwin@ashwin-X550LD:~/Project$ python filemgr.py 
ashwin@ashwin-X550LD:~/Project$ python3 filemgr.py 
  File "filemgr.py", line 23
    if extension==".jpeg" or extension==".jpg" or extension==".JPG" or extension==".png" or extension==".PNG":
                                                                                                             ^
TabError: inconsistent use of tabs and spaces in indentation

答案1

你真正想要的

查看您的编辑,您真正想要的是创建文件夹:

图片
文档
歌曲
视频
数据库
其他

而不是像在原始脚本

原则

第一条规则始终是:如果你多次执行同一件事,那么就将其变成一个函数。重复执行同一件事会不必要地冗长,使你的代码难以维护(更改),难以阅读且看起来丑陋。

用一个功能, 代替:

if extension==".jpeg" or extension==".jpg" or extension==".JPG" or extension==".png" or extension==".PNG":
new_dir = reorg_dir+"/Pictures"
elif extension==".docx" or extension==".doc" or extension==".pdf" or extension==".xlsx" or extension==".ppt" or extension==".pptx":
new_dir = reorg_dir+"/Documents"
elif extension==".mp3" or extension==".MP3":
new_dir = reorg_dir+"/Songs"
elif extension==".mp4" or extension==".MP4" or extension==".avi" or extension==".AVI":
new_dir = reorg_dir+"/Videos"
elif extension==".db" or extension==".DB":
new_dir = reorg_dir+"/Databases"
elif extension=="*.*":
    new_dir = reorg_dir+"/Others"

您可以使用:

def dir_names(ext):
    extensions = [
        [["jpeg", "jpg", "png"], "Pictures"],
        [["mp4", "avi"], "Videos"],
        [["docx", "doc", "pdf", "xlsx", "ppt", "pptx"], "Documents"],
        [["mp3"], "Songs"],
        [["db"], "Database"],
        ]
    match = [item[1] for item in extensions if ext.lower() in item[0]]
    return match[0] if match else "Others"

“计算”目标文件夹名称。随后应用以下行中的函数:

extension = dir_names(name[name.rfind(".")+1:]) # edited line

整个脚本就变成:

#!/usr/bin/env python3

import os
import subprocess
import shutil

# --------------------------------------------------------
reorg_dir = "/media/ashwin/Work+Entertainment/Untitled Folder"
exclude = () # for example
remove_emptyfolders = True
# ---------------------------------------------------------

def dir_names(ext):
    extensions = [
        [["jpeg", "jpg", "png"], "Pictures"],
        [["mp4", "avi"], "Videos"],
        [["docx", "doc", "pdf", "xlsx", "ppt", "pptx"], "Documents"],
        [["mp3"], "Songs"],
        [["db"], "Database"],
        ]
    match = [item[1] for item in extensions if ext.lower() in item[0]]
    return match[0] if match else "Others"

for root, dirs, files in os.walk(reorg_dir):
    for name in files:
        subject = root+"/"+name
        if name.startswith("."):
            extension = "hidden_files"
        elif not "." in name:
            extension = "without_extension"
        else:
            extension = dir_names(name[name.rfind(".")+1:]) # edited line
        if not extension in exclude:
            new_dir = reorg_dir+"/"+extension
            if not os.path.exists(new_dir):
                os.mkdir(new_dir)
            shutil.move(subject, new_dir+"/"+name)

def cleanup():
    filelist = []
    for root, dirs, files in os.walk(reorg_dir):
        for name in files:
            filelist.append(root+"/"+name)
    directories = [item[0] for item in os.walk(reorg_dir)]
    for dr in directories:
        matches = [item for item in filelist if dr in item]
        if len(matches) == 0:
            try:
                shutil.rmtree(dr)
            except FileNotFoundError:
                pass

if remove_emptyfolders == True:
    cleanup()

功能说明

def dir_names(ext):
    extensions = [
        [["jpeg", "jpg", "png"], "Pictures"],
        [["mp4", "avi"], "Videos"],
        [["docx", "doc", "pdf", "xlsx", "ppt", "pptx"], "Documents"],
        [["mp3"], "Songs"],
        [["db"], "Database"],
        ]
    match = [item[1] for item in extensions if ext.lower() in item[0]]
    return match[0] if match else "Others"
  • extension是一个列表,其中每个列表项都存在一个扩展名(小写)的子列表和您想要将其移动到的相应文件夹。
  • 该函数只是检查扩展名(较低)是否在扩展列表中,然后返回相应的(所需的)文件夹名称。
  • 如果扩展名不在任何子列表,该函数返回Others

为什么你的代码不起作用

除了编码效率低下的问题外,建议的代码还存在其他一些问题,其中缩进是最重要的。(在if/else必须缩进,或者使用如下一行:

monkey = animal if 1 == 1 else vegetable

在python中,缩进是必不可少的。

运行python代码时,解释器通常会以非常易读的格式指出错误。始终从下向上阅读错误消息。

答案2

Python 对空格敏感,这意味着您必须正确缩进代码;否则您会收到错误...

在一个if块之后,您需要缩进代码,您可以使用Tab来执行此操作。

您的代码应如下所示:

#!/usr/bin/env python3

import os
import subprocess
import shutil

# --------------------------------------------------------
reorg_dir = "/media/ashwin/Work+Entertainment/Untitled Folder"
exclude = () 
remove_emptyfolders = True
# ---------------------------------------------------------

for root, dirs, files in os.walk(reorg_dir):
    for name in files:
        subject = root+"/"+name
        if name.startswith("."):
            extension = ".hidden_files"
        elif not "." in name:
            extension = ".without_extension"
        else:
            extension = name[name.rfind("."):]
        if not extension in exclude:
            if extension==".jpeg" or extension==".jpg" or extension==".JPG" or extension==".png" or extension==".PNG":
                new_dir = reorg_dir+"/Pictures"
            elif extension==".docx" or extension==".doc" or extension==".pdf" or extension==".xlsx" or extension==".ppt" or extension==".pptx":
                new_dir = reorg_dir+"/Documents"
            elif extension==".mp3" or extension==".MP3":
                new_dir = reorg_dir+"/Songs"
            elif extension==".mp4" or extension==".MP4" or extension==".avi" or extension==".AVI":
                new_dir = reorg_dir+"/Videos"
            elif extension==".db" or extension==".DB":
                new_dir = reorg_dir+"/Databases"
            elif extension=="*.*":
                new_dir = reorg_dir+"/Others"

        if not os.path.exists(new_dir):
                os.mkdir(new_dir)
            n = 1; name_orig = name
            while os.path.exists(new_dir+"/"+name):
                name = name_orig
                n = n+1
            newfile = new_dir+"/"+name
            shutil.move(subject, newfile)

def cleanup():
    filelist = []
    for root, dirs, files in os.walk(reorg_dir):
        for name in files:
            filelist.append(root+"/"+name)
    directories = [item[0] for item in os.walk(reorg_dir)]
    for dr in directories:
        matches = [item for item in filelist if dr in item]
        if len(matches) == 0:
            try:
                shutil.rmtree(dr)
            except FileNotFoundError:
                pass

if remove_emptyfolders == True:
    cleanup()

答案3

您必须在该行及其下方添加标识。Python 使用标识来标识代码块,并且 if 语句下方的代码应该被标识,因为它属于 if 块。根据 PEP8,标准标识是 4 个空格。

相关内容