Python неожиданно перемещает файлы с помощью os.rename

У меня есть скрипт, который:

  1. Перебирает все файлы в каталоге + его подкаталогах
  2. Создает папку для каждого уникального года в списке файлов
  3. Перемещает файлы в соответствующие папки по годам
  4. Переименовывает их на основе метки времени + уникальный номер.

Когда я запускаю только части 1-3, он правильно перемещает файлы в папки.

Когда я запускаю части 1-4 (включая часть os.rename), он переименовывает файлы ПОСЛЕ перемещения и возвращает их в родительский каталог.

Начальная структура файла:

parent_folder
      --> file.txt    modified 01-21-2012
      --> file2.txt   modified 09-30-2013
      --> file3.txt   modified 06-21-2017

Ожидаемый результат:

parent_folder
--> '2012'
      --> 2012-01-21-1.txt
--> '2013'
      --> 2013-09-30-2.txt
--> '2017'
      --> 2017-06-21-3.txt

Фактический результат:

parent_folder
--> '2012'
--> '2013'
--> '2017'
--> '2012-01-21-1.txt'
--> '2013-09-30-2.txt'
--> '2017-06-21-4.txt'

Как видите, он переименовал файлы, но переместил их из своих папок. Почему он это делает?

Мой код (я вставил печатные операторы для регистрации):

import os, datetime, sys, shutil

#PART 1 : Change to the inputted directory
#===============================

# This is the directory I will work on.
p = 'ENTER_FOLDER_PATH_HERE'
print('This is the directory that will be organized:')
print(os.getcwd())
if os.path.isdir(p): # check if directory exists
    print("Step 1: Changing directory")
    os.chdir(p)

#PART 2 : Make a folder for each unique year
#===========================================
    fileNames = next(os.walk(os.getcwd()))[2] # list files, excluding subdirectories
    f = {}
    filename = []
    dates = []

    # Loop through each file and grab the unique year.
    # Store the file (key) and its modified year (value) into dictionary 'f'.
    for name in fileNames:
        f[name] = datetime.datetime.fromtimestamp(os.path.getmtime(name)).strftime("%Y")
        dates = list(set(f.values()))

    # Create the list of unique folders from the dictionary.
    print("Step 2: Creating the following folders:\n", dates)
    print('\n')
    [os.mkdir(folder) for folder in dates]


#PART 3: Move all files to their respective folders based on modified year.
#==========================================================================
    if sys.platform == 'Windows':
        print("Step 3: moving files...")
        [shutil.move(key, os.getcwd() + '\\' + value) for key, value in f.items()]
    elif sys.platform == 'darwin':
        print("Step 3: moving files...")
        [shutil.move(key, os.getcwd() + '//' + value) for key, value in f.items()]
    else:
        print("Sorry, this script is not supported in your OS.")
else:
    print("Oops, seems like that directory doesn't exist. Please try again.")


#PART 4: Rename the files
#==========================================================================
# Get each file in directory and renames it to its modified date, Y-M-D format
count=1
for root, dir, files in os.walk(p):
    for file in files:
        if not file.startswith('.'): # ignore hidden files
            filePath = os.path.join(root,file)
            ext = os.path.splitext(filePath)[1]
            print("File number: ", count, file, ext)
            print('\n')
            os.rename(filePath, datetime.datetime.fromtimestamp(os.path.getmtime(filePath)).strftime("%Y-%m-%d") + '-' + str(count) + ext)
        count += 1
        print(filePath)

Журналы:

This is the directory that will be organized:
TEST_PATH
Step 1: Changing directory
Step 2: Creating the following folders:
 ['2013', '2012', '2017']


Step 3: moving files...
File number:  1 2012-01-21-1.jpg TEST_PATH/2012/2012-01-21-1.jpg
TEST_PATH//2012/2012-01-21-1.jpg

File number:  2 2013-09-30-2.jpg TEST_PATH/2013/2013-09-30-2.jpg
TEST_PATH/2013/2013-09-30-2.jpg
TEST_PATH/2013/2013-09-30-2.jpg

File number:  4 June 21 2017.txt TEST_PATH/2017/June 21 2017.txt
TEST_PATH/2017/June 21 2017.txt

1 ответ

Решение

Он перемещает файл из-за рабочего каталога, в котором вы находитесь. Я думаю, он работает так же, как mv команда. Полученный файл после ранама будет помещен в путь, указанный вторым аргументом os.rename функция относительно cwd, Если вы хотите, чтобы он работал правильно, вам нужно указать относительный путь с новым именем файла.

Btw. Вы можете выполнить шаги 3 и 4 одновременно.

Другие вопросы по тегам