Python:创建名称较短的文件路径)?

Python: Recreate file path with shorter name(s)?

D:\MyDir 包含大量带或不带子目录的目录,这些目录可能包含也可能不包含一个或多个文件。

其中一些子目录 and/or 文件的名称也很长 +/- 很长,这导致该文件的路径名很大。

例如

D:\MyDir:
"Very large directory name"\
    "Very large directory name"\ 
#OPTIONAL
#other or the same name repeating one or more times
        "normal dir"\ #optional
             Long_or_normal_name_MyFile.html and Long_or_normal_name_MyFile.html and so on...

我想创建一个 Python 脚本:

  1. 将文件移动到名为“非常大的目录名称”的第一个目录(基本目录)。
  2. 用较短的名称重命名文件。
  3. 用较短的名称重命名基本目录,然后删除留下的空目录。

要移动文件或文件夹,我可以使用 shutil.move()。

使用这段代码,我列出了目录中的所有文件并将它们存储到列表中:

from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]

而这一行将仅列出 D:\MyDir 中的一级目录并将它们存储到列表中:

[ name for name in os.listdir(thedir) if os.path.isdir(os.path.join(thedir, name)) ]

但是如何进一步做才能完成我需要做的事情?

忘了说 D:\MyDir 还包含不需要重命名的目录和文件 and/or 已移动。

提前致谢!

您可以遍历每个要更改的文件夹到最底层。将底部的每个文件向上移动两层并更改其名称。然后在备份过程中删除所有空文件夹。然后最后更改目录本身的名称。

这是一个例子。不知道你计划重命名每个文件夹 和文件我只是把他们现在的名字切成两半。我确实保留了文件扩展名,并通过在末尾添加唯一编号来检查以确保重命名的文件不会相互覆盖。

import os, shutil
from pathlib import Path

def traverse(current):
    if current.is_file(): # if current path is a file
      
        # cut the name in half
        half = current.stem[:len(current.stem)//2]     
      
        # get path for two directories above 
        base = current.parent.parent.parent         
        num = 1      # number to add to filename so to avoid duplicates
      
        # check for files with the same name
        while os.path.exists(base / (half + str(num) + current.suffix)): num += 1                                  
   
        # move the file up two levels and change filename
        shutil.move(current, base / (half + str(num) + current.suffix))  
    
    elif current.is_dir():    # if current is a directory
    
        # iterate and recurse each item in the current directory
        for item in current.iterdir(): traverse(item)        
    
        # if the resulting directory is empty delete it
        if not len(os.listdir(current)): shutil.rmtree(current)  

basedirs = ["Very large directory name1", "Very large directory name2"]

for folder in basedirs:    # iterate folder list
    path = Path(folder) 
    traverse(path)         # traverse the directory
    num = 1
    newpath = path.name[:len(path.name) // 2] #cut directory name in half
    while os.path.exists(path.parent / (newpath + str(num))): num += 1
    shutil.move(folder, path.parent / (newpath + str(num)))  # rename directory