簡體   English   中英

將文件名稱更改為父文件夾名稱

[英]Changing name of the file to parent folder name

我的目錄中有一堆文件夾。 他們每個人都有一個文件,您可以在下面看到:

在此處輸入圖像描述

不管文件擴展名是什么,我都希望這個文件的名稱與其父文件夾完全相同,即在考慮文件夾 2023-10-18 時,我希望文件位於2023-10-18而不是掩星。 ...

我嘗試使用此線程重命名多個文件:

使用 Python 重命名目錄中的多個文件

和這里

https://pynative.com/python-rename-file/#:~:text=Use%20rename()%20method%20of,function%20to%20rename%20a%20file

但不幸的是,在應用了這樣的代碼之后:

 import os
 from pathlib import Path
 pth = Path(__file__).parent.absolute()
 files = os.listdir(pth)

 for file in files:
 os.rename(os.pth.join(pth, file), os.pth.join(pth, '' + file + '.kml'))

我有一個錯誤:

AttributeError: 模塊 'os' 沒有屬性 'pth'

此處描述:

AttributeError: 'module' object 沒有屬性

這對我來說只是一點點,因為我是 Python 的新手。

如何自動更改這些目錄中所有文件的名稱? 我需要與目錄名相同的文件名。 是否可以?

更新:

在下面提示之后,我的代碼現在看起來像這樣:

 import os
 from pathlib import Path
 pth = Path(__file__).parent.absolute()
 files = os.listdir(pth)

 for file in files:
  os.rename(os.path.join(pth, file), os.path.join(pth, '' + file + '.kml'))

但不是更改文件夾列表中的文件名,而是將給定目錄中的所有文件更改為 .kml。 如何訪問文件夾列表中的各個文件?

在此處輸入圖像描述

因此,根據我的理解,每個文件夾中都有一個文件。 您想要使用相同的文件夾名稱重命名文件並保留擴展名。

import os

# Passing the path to your parent folders
path = r'D:\bat4'

# Getting a list of folders with date names
folders = os.listdir(path)

for folder in folders:
    files = os.listdir(r'{}\{}'.format(path, folder))

    # Accessing files inside each folder
    for file in files:

        # Getting the file extension
        extension_pos = file.rfind(".")
        extension = file[extension_pos:]

        # Renaming your file
        os.rename(r'{}\{}\{}'.format(path, folder, file),
                  r'{}\{}\{}{}'.format(path, folder, folder, extension))

我在我自己的文件上試過如下:

在此處輸入圖像描述

在此處輸入圖像描述

這是 output 的示例:

在此處輸入圖像描述

我希望我明白你的意思。 :)

這是一個僅使用osshutil模塊的簡單解決方案,它們都已預安裝。 它是跨平台的,對我來說工作得很好而且很快。 它還可以處理每個子文件夾中的多個文件。

我認為您可以從評論中理解代碼,但如果不是這樣,請隨時通知我。

import os, shutil
from os.path import * # just to avoid typing "os.path." everywhere

# I am using abspath() here to get the absolute path to the folder.
folder = abspath(input('Enter the main folder: '))

# index through all elements in the main folder that are directories
for subfolder in os.listdir(folder):
    abs_subfolder = join(folder, subfolder) # get the folder's absolute path
    if not isdir(abs_subfolder):
        continue # go to the next element because this one wasn't a folder

    # index through all the files in this subfolder
    for file in os.listdir(abs_subfolder):
        # get the extension of the file to move
        extension = splitext(file)[1]

        new_file_path = abs_subfolder + '.' + extension

        # move the file to its parent directory, and change its name
        shutil.move(join(abs_subfolder, file), new_file_path)

    # delete the directory the files were in
    # you can comment the next line if you don't want that to happen
    os.rmdir(abs_subfolder)

基本上,這段代碼所做的是對包含所有這些子文件夾及其中的文件的文件夾內的每個目錄進行索引。

然后,它搜索每個子文件夾中的每個文件,然后將這些文件移動到主文件夾,同時將它們的名稱更改為它們所在的子文件夾。

最后,一旦該子文件夾的每個文件都被移動並重命名,它就會刪除空目錄。 如果您不希望這種情況發生,您可以只評論最后一行。

我希望這有幫助。


另外,我不知道你的代碼是從哪里來的,但你到處都是.kml的原因是因為代碼所做的就是將所有文件夾重命名為它們的名稱 + .kml 它甚至不涉及子文件夾中的文件。 我不認為我可以讓你的代碼按你想要的方式工作而不改變其中的幾乎所有內容。


如果您想了解有關os模塊的更多信息,請查看此頁面以及os.path這一頁面。 我會說shutil只是os模塊的“補充”,它與 is 有一些相似之處,但您可以在此處查看完整文檔。

如果你想總體上學習 Python,我認為w3schools是 go 的最佳去處。

每行代碼推理都有注釋! 每個答案都應該使用iglob ,請在此處閱讀更多相關信息! 該代碼也是后綴不可知的( .klm因為后綴不是硬編碼的),並且適用於需要此實用程序的任何場景。

只使用了標准的庫函數。

最滿意的方法:移出目錄,重命名,刪除目錄

import os
from shutil import move
from glob import iglob
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor


# The .py file has to be on the same directory as the folders containing the files!
root = Path(__file__).parent

# Using threading in case the operation becomes I/O bound (many files)
with ThreadPoolExecutor() as executor:
    for file in iglob(str(root / "**" / "*")):
        file = Path(file)

        # The new filename is the name of the directory, and the suffix(es) of the original file
        new_filename = f"{file.parent.name}{''.join(file.suffixes)}"

        # Move AND rename simultaneosly
        executor.submit(move, file, root / new_filename)

        # Delete directory because it is empty, and has no utility; ommit this line if not True
        executor.submit(os.rmdir, file.parent)

不太滿意; OPs請求:重命名文件(保留在目錄內)

如果您真的只想重命名文件,並將它們保存在各自的目錄中:

import os
from shutil import move
from glob import iglob
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor


RENAME_ONLY = True


# The .py file has to be on the same directory as the folders containing the files!
root = Path(__file__).parent

# Using threading in case the operation becomes I/O bound
with ThreadPoolExecutor() as executor:
    for file in iglob(str(root / "**" / "*")):
        file = Path(file)

        # The new filename is the name of the directory, and the suffix(es) of the original file
        new_filename = f"{file.parent.name}{''.join(file.suffixes)}"

        if RENAME_ONLY:
            executor.submit(os.rename, file, file.parent / new_filename)
        else:
            # Move AND rename simultaneosly
            executor.submit(move, file, root / new_filename)

            # Delete directory because it is empty, and has no utility; ommit this line if not True
            executor.submit(os.rmdir, file.parent)

為什么''.join(file.suffixes)

有些文件有多個句點; abc.x.yz 我們得到帶有.yzfile.suffix.x.yz ''.join(file.suffixes) 因此我選擇使用后者。

這是對子后綴的敏感性問題,這通常很重要。 例如, .tar.gz文件file.suffix不會捕獲.tar ,這對文件格式有害。

您需要將它保存到一個文件(例如,rename.py)並使用 python 解釋器和一個附加參數調用它 - 您要為其子目錄中的文件重命名的父目錄的名稱。 例如:“python rename.py parent_dir”。 目錄名可以是絕對的或相對的。 作為附加參數,您還可以在重命名文件時指定用於保存擴展名的密鑰(0 - 不保存,1 - 保存)。 默認情況下不保存擴展名。 這是保存擴展名的示例:“python rename.py parent_dir 1”。

rename.py 中的腳本:

import os
import sys

def rename_first_file_in_dir(dir_path, new_file_name, keep_extension = False):
  for current_file_name in os.listdir(dir_path):
    current_file_path = os.path.join(dir_path, current_file_name) # full or relative path to the file in dir
    if not os.path.isfile(current_file_path):
      break
    # rename only base name of file to the name of directory
    if keep_extension:
      file_extension = os.path.splitext(current_file_name)[1]
      if len(file_extension) > 0:
        new_file_name = new_file_name + file_extension 
        
    new_file_path = os.path.join(dir_path, new_file_name)
    print("File " + current_file_name + " renamed to " + new_file_name + " in " + os.path.basename(dir_path) + " directory");
    os.rename(current_file_path, new_file_path)
    # exit after first processed file
    break

if len(sys.argv) < 2:
  print("Usage: python " + os.path.basename(__file__) + " <directory> [keep_files_extensions]") # help for usage
  exit(0)
scan_dir = sys.argv[1]
keep_extension = False if len(sys.argv) < 3 else not (int(sys.argv[2]) == 0) # optional parameter 0 - False, 1 - True, by default - False
if not os.path.exists(scan_dir):
  print("Error: directory " + scan_dir + " does not exists")
  exit(-1)
if not os.path.isdir(scan_dir):
  print("Error: file " + scan_dir + " is not a directory")
  exit(-1)
print("Scanning directory " + scan_dir)
for file_name in os.listdir(scan_dir): # walk through directory
  file_path = os.path.join(scan_dir, file_name)
  if os.path.isdir(file_path):
    rename_first_file_in_dir(file_path, file_name, keep_extension)

這里有一個使用 pathlib 模塊的示例代碼。 請務必修改 base_folder。

解決方案 1

"""
rename_filename.py

Rename filename inside the folders.

https://stackoverflow.com/questions/71408697/changing-name-of-the-file-to-parent-folder-name


Example:

base_folder
F:/Tmp/s13/

sub_folders
F:/Tmp/s13/2022-05-01
F:/Tmp/s13/2022-08-01

files under subfolder
F:/Tmp/s13/2022-05-01/aa.txt
F:/Tmp/s13/2022-08-01/bb.txt


Usage:

Be sure to modify first the "base_folder" value in the main()

command lines:
python rename_filename.py or
python3 rename_filename.py
"""

from pathlib import Path  # python version >= 3.4


def rename_file(base_folder):
    """
    Rename the filename of the file under the sub-folders of the base_folder.
    """
    base_path = Path(base_folder).glob('*/*')

    # Get the file path in every sub-folder.
    for file in base_path:
        # print(file)
        sub_folder_abs_path = file.parent  # sub-folder path, F:/Tmp/s13/2022-05-01
        sub_folder_name = file.parent.name  # sub-folder name, 2022-05-01

        # Rename the file to sub-folder name.
        new_file = Path(sub_folder_abs_path, sub_folder_name)
        file.rename(new_file)


def main():
    # Change the base folder according to your case.
    base_folder = 'F:/Tmp/s13/'
    rename_file(base_folder)


if __name__ == '__main__':
    main()

方案二
使用 pathlib 和 argparse 模塊。 它提供 --base-folder 選項來定位基本文件夾,無需修改源。 見用法。

"""
rename_file.py

Rename filename inside the folders.

https://stackoverflow.com/questions/71408697/changing-name-of-the-file-to-parent-folder-name


Example:

base_folder
F:/Tmp/s13/

sub_folders
F:/Tmp/s13/2022-05-01
F:/Tmp/s13/2022-08-01

files under subfolder
F:/Tmp/s13/2022-05-01/aa.txt
F:/Tmp/s13/2022-08-01/bb.txt


Usage:

command line:

python rename_file.py --base-folder "F:/Tmp/s13/"
"""

from pathlib import Path  # python version >= 3.4
import argparse


def rename_file(base_folder):
    """
    Rename the filename of the file under the sub-folders of the base_folder.
    """
    base_path = Path(base_folder).glob('*/*')

    # Get the file path in every sub-folder.
    for file in base_path:
        # print(file)
        sub_folder_abs_path = file.parent  # sub-folder path, F:/Tmp/s13/2022-05-01
        sub_folder_name = file.parent.name  # sub-folder name, 2022-05-01

        # Rename the file to sub-folder name.
        new_file = Path(sub_folder_abs_path, sub_folder_name)
        file.rename(new_file)


def main():
    parser = argparse.ArgumentParser(description='Rename file to sub-folder name.')
    parser.add_argument('--base-folder', required=True,
                        help='the base folder, example: --base-folder "f:/tmp/so13/"')

    args = parser.parse_args()
    rename_file(args.base_folder)


if __name__ == '__main__':
    main()

用法:
打開命令提示符和 CD 到 rename_file.py 的位置。

python rename_file.py --base-folder "f:/tmp/s13/"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM