将文件分组到某些文件夹中

将文件分组到某些文件夹中

我有一些文件,它们的扩展名不同,例如*.pdf,,以及其他一些。它们都存储在一个目录中。*.mp3*.jpgparent

我如何获取所有扩展的列表,根据这些扩展创建一些文件夹,然后将所有文件移动到其相关文件夹中?

答案1

下面的python脚本可以完成这个任务。隐藏文件和没有扩展名的文件分别存储在文件夹中。

由于它可能用于更广泛的用途,因此我添加了一些选项:

  • 您可以设置要从“重组”中排除的扩展。如果您只想移动所有内容,请设置exclude = ()
  • 您可以选择如何处理空文件夹(remove_emptyfolders = TrueFalse
  • 如果你想复制文件而不是移动将下面这一行替换掉:
shutil.move(subject, new_dir+"/"+name)

经过:

shutil.copy(subject, new_dir+"/"+name) 

剧本:

#!/usr/bin/env python3

import os
import subprocess
import shutil

# --------------------------------------------------------
reorg_dir = "/path/to/directory_to_reorganize"
exclude = (".jpg") # for example
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:
            new_dir = reorg_dir+"/"+extension[1:]
            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()

如果存在不必要的覆盖重复文件的风险

只需多写几行代码,我们就可以防止覆盖可能的重复项。使用以下代码,重复项将被重命名为:

duplicate_1_filename, duplicate_2_filename 

ETC。

剧本:

#!/usr/bin/env python3

import os
import subprocess
import shutil

# --------------------------------------------------------
reorg_dir = "/path/to/directory_to_reorganize"
exclude = (".jpg") # for example
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:
            new_dir = reorg_dir+"/"+extension[1:]
            if not os.path.exists(new_dir):
                os.mkdir(new_dir)
            n = 1; name_orig = name
            while os.path.exists(new_dir+"/"+name):
                name = "duplicate_"+str(n)+"_"+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()

编辑

考虑到 OP,我们都忘了添加如何使用的说明。由于重复的问题可能(并做) 出现,但它仍然可能是有用的。

如何使用

  1. 将其中一个脚本复制到一个空文件中,并将其另存为reorganize.py
  2. 在脚本的头部部分,设置目标目录(包含要重新组织的文件):

    reorg_dir = "/path/to/directory_to_reorganize" 
    

    (如果目录包含空格,请使用引号)

    您可能想要排除的扩展(可能没有,如下所示):

    exclude = ()
    

    如果您想随后删除空文件夹:

    remove_emptyfolders = True
    
  3. 使用以下命令运行脚本:

    python3 /path/to/reorganize.py
    

注意:如果你想复制文件而不是移动, 代替:

shutil.move(subject, new_dir+"/"+name)

经过:

shutil.copy(subject, new_dir+"/"+name)

请先试用小样本。

答案2

您可以使用find有点复杂的exec命令:

find . -iname '*?.?*' -type f -exec bash -c 'EXT="${0##*.}"; mkdir -p "$PWD/${EXT}_dir"; cp --target-directory="$PWD/${EXT}_dir" "$0"' {} \;

# '*?.?*' requires at least one character before and after the '.', 
# so that files like .bashrc and blah. are avoided.
# EXT="${0##*.}" - get the extension
# mkdir -p $PWD/${EXT}_dir - make the folder, ignore if it exists

替换cpecho以进行空运行。


更高效、更整洁的方法是将bash命令保存在脚本中(例如,在 /path/to/the/script.sh):

#! /bin/bash

for i
do
    EXT="${i##*.}" 
    mkdir -p "$PWD/${EXT}_dir"
    mv --target-directory="$PWD/${EXT}_dir" "$i" 
done

然后运行find

find . -iname '*?.?*' -type f -exec /path/to/the/script.sh {} +

这种方法非常灵活。例如,要使用文件名而不是扩展名(filename.ext),我们可以将其用于EXT

NAME="${i##*/}"
EXT="${NAME%.*}"

答案3

ls | gawk -F. 'NF>1 {f= $NF "-DIR"; system("mkdir -p " f ";mv " $0 " " f)}'

计算扩展列表(移动后):

ls -d *-DIR

计算扩展列表(移动之前):

ls -X | grep -Po '(?<=\.)(\w+)$'| uniq -c | sort -n

(在最后一个例子中,我们计算每个扩展名的文件数量并对其进行排序)

答案4

如果您安装了 Perl 的 rename/prename:

rename 's!(.*)\.(\w+)$! mkdir($2); "$2/$&"!ge'  *

相关内容