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

αғs*_*нιη 12 file-format filemanager

我有不同的扩展名,如一些文件*.pdf*.mp3*.jpg和其他几个人。所有这些都存储在一个parent目录中。

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

Jac*_*ijm 14

下面的python脚本可以完成这项工作。隐藏文件单独存放在一个文件夹中,以及没有扩展名的文件。

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

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

经过:

shutil.copy(subject, new_dir+"/"+name) 
Run Code Online (Sandbox Code Playgroud)

剧本:

#!/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()
Run Code Online (Sandbox Code Playgroud)

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

以增加几行为代价,我们可以防止覆盖可能的重复项。使用下面的代码,重复项将重命名为:

duplicate_1_filename, duplicate_2_filename 
Run Code Online (Sandbox Code Playgroud)

等等。

剧本:

#!/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()
Run Code Online (Sandbox Code Playgroud)

编辑

考虑到OP,我们都忘记添加有关如何使用的说明。由于可能(并且确实)出现重复的问题,因此它可能仍然有用。

如何使用

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

    reorg_dir = "/path/to/directory_to_reorganize" 
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    exclude = ()
    
    Run Code Online (Sandbox Code Playgroud)

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

    remove_emptyfolders = True
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用以下命令运行脚本:

    python3 /path/to/reorganize.py
    
    Run Code Online (Sandbox Code Playgroud)

注意,如果您想复制文件而不是move,请替换:

shutil.move(subject, new_dir+"/"+name)
Run Code Online (Sandbox Code Playgroud)

经过:

shutil.copy(subject, new_dir+"/"+name)
Run Code Online (Sandbox Code Playgroud)

请先尝试小样本。


mur*_*uru 12

您可以使用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
Run Code Online (Sandbox Code Playgroud)

更换cpecho的预演。


bash命令保存在脚本中(例如 at /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
Run Code Online (Sandbox Code Playgroud)

然后运行find

find . -iname '*?.?*' -type f -exec /path/to/the/script.sh {} +
Run Code Online (Sandbox Code Playgroud)

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

NAME="${i##*/}"
EXT="${NAME%.*}"
Run Code Online (Sandbox Code Playgroud)


小智 6

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

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

ls -d *-DIR
Run Code Online (Sandbox Code Playgroud)

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

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

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


小智 5

试试这个 shell 脚本。

#!/bin/sh
src=`dirname "$1"`/`basename "$1"`;
for file in "$src"/*?.?*; do
  if test -f "$file"; then
    dest="$src${file##*.}"_files;
    mkdir -p "$dest";
    mv "$file" "$dest";
  fi;
done;

# pass the directory to re-organize as first argument
# moves only regular files which have extension
# ignores other type of files including
# files having no extension, hidden files, directories, and links.
Run Code Online (Sandbox Code Playgroud)