web-dev-qa-db-ja.com

拡張子ごとにファイルを再編成し、カテゴリごとにフォルダに分類するにはどうすればよいですか?

以下のコードは@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
2
Ashwin Joshi

その行以下にIDを追加する必要があります。 PythonはIDを使用してコードブロックを識別し、ifブロックに属するためifステートメントの下のコードを識別する必要があります。PEP8による標準識別は4スペースです。

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()
1
TellMeWhy

あなたが実際に欲しいもの

編集内容を見て、実際に必要なのはフォルダーを作成することです。

写真
ドキュメント

動画
データベース
その他

元のスクリプト のように、拡張子にちなんで名付けられたフォルダの代わりに。

原則

最初のルールは常に次のとおりです。同じことを複数回行う場合は、それを関数にします。同じことを繰り返すと不必要に冗長になり、コードの保守(変更)が難しくなり、読みづらくて見苦しくなります。

次の代わりにfunctionを使用します。

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はリストです。リストのすべてのリスト項目は、拡張のサブリスト(小文字)とそれに対応する移動先のフォルダーです。
  • この関数は、拡張子(下側)が拡張子リストにあるかどうかを確認し、対応する(望ましい)フォルダー名を返します。
  • 拡張がサブリストのanyの拡張リストにない場合、関数はOthersを返します。

コードが機能しない理由

非効率的なコーディングの問題とは別に、提案されたコードには、インデントが最も重要ないくつかの他の問題があります。 (if/elseの後mustインデント、orのような行を使用:

monkey = animal if 1 == 1 else vegetable

Pythonでは、インデントが不可欠です。

pythonコードを実行すると、通常、インタープリターによってかなり読みやすい形式でエラーが示されます。エラーメッセージは常に上から下に向かって読み始めます。

1
Jacob Vlijm