Как переименовать части имени файла в Python - PullRequest
0 голосов
/ 11 апреля 2019

Я пытаюсь переименовать несколько файлов, используя Python, чтобы они следовали новому соглашению об именах, которое выглядит следующим образом:

~/directory/yyyy + qq + directory_name + ' Letter'.

Сейчас они находятся в этом формате:

~/directory/directory_name + yyyy + qq + ' Letter'.

Так, например, у меня есть каталог с именем /Users/Test/rename_test/Salmon 2, и в нем находятся следующие файлы:

  • /Users/Test/rename_test/Salmon 2/Salmon 2 2013 Q4 Letter.pdf
  • /Users/Test/rename_test/Salmon 2/Salmon 2 2018 Q1 Letter.pdf
  • /Users/Test/rename_test/Salmon 2/Salmon 2 2015 Q2 Letter.pdf

Я хотел бы переименовать все эти файлы в:

  • /Users/Test/rename_test/Salmon 2/2013 Q4 Salmon 2 Letter.pdf
  • /Users/Test/rename_test/Salmon 2/2018 Q1 Salmon 2 Letter.pdf
  • /Users/Test/rename_test/Salmon 2/2015 Q2 Salmon 2 Letter.pdf

Я смотрел на использование os.split для извлечения позиций [-2] и [-3] - с тех пор должен всегда быть qq и гггг - и затем переименовать файл, переместив их в позиции [0] и [1].Но у меня есть сотни каталогов и тысячи файлов, поэтому я беспокоюсь, что одна опечатка или файл, который отличается от текущего соглашения, может привести к ошибке.

Так, как лучше всего подойти к этому?

Ответы [ 3 ]

0 голосов
/ 11 апреля 2019

Вы можете использовать os.rename или shutil (см. здесь ).

В вашем случае, если ваша структура имен точно соответствует той, которую вы опубликовали, вы можете сделать это без регулярного выражения:

import shutil
old_path = '/Users/Test/rename_test/Salmon 2/Salmon 2 2013 Q4 Letter.pdf'
x = old_path.split(os.sep)[-1].split()
x = ' '.join((x[2],x[3],x[0],x[1],x[3],x[4]))
new_path = os.sep.join(old_path.split(os.sep)[0:-1] + [x])
#shutil.move(old_path, new_path)
shutil.copyfile(old_path, new_path)

ПОПРОБУЙТЕ с печатными заявлениями, пожалуйста!


Вам придется обернуть это циклом for для всех файлов. Лучше скопировать в новый каталог, а затем вручную подтвердить результаты.

import glob
for f in glob.glob('/Users/Test/rename_test/Salmon 2/*.pdf'):
    # code above, where old_path = f

Это еще одна причина использовать копирование вместо перемещения, потому что если вы переименуете файлы в один и тот же каталог с тем же расширением, они будут извлекаться каждый раз, когда вы запускаете код (и нарушаете приведенный выше код).

0 голосов
/ 12 апреля 2019

Вы можете попробовать использовать re.sub() для выполнения манипуляции с именем.Например:

import re
import os

old_path = '/Users/Test/rename_test/Salmon 2/Salmon 2 2013 Q4 Letter.pdf'
old_filename = os.path.basename(old_path) # Salmon 2 2013 Q4 Letter.pdf
directory = os.path.basename(os.path.dirname(old_path)) # Salmon 2

new_filename = re.sub(r'('+ directory +')\s([0-9]{4})\s(Q[1-9]?[0-9]*)\sLetter\.pdf',r'\2 \3 \1 Letter.pdf', old_filename) # 2013 Q4 Salmon 2 Letter.pdf

Как видите, этот метод позволяет вам определить шаблон, в котором вы можете идентифицировать группы с круглыми скобками (...), а затем вы можете переставить строку, используя эти группы в том порядке, в каком вам нравится,Каждую группу можно выбрать с помощью \n, где n - номер группы.

Для получения дополнительной информации: https://docs.python.org/3.6/library/re.html#re.sub

0 голосов
/ 11 апреля 2019

Ваша идея в основном здорова, но вы можете добавить хотя бы два шага, чтобы сделать ее более безопасной:

  1. использует регулярное выражение, которое определяет ваш формат и выдает ошибку, если оно не совпадает. Например. Ваше регулярное выражение может выглядеть так:

    ^ Лосось 2 \ d {4} Q \ d {1} Буква

Вам необходимо заменить Salmon 2 через переменную, которая содержит ваше текущее имя dir

  1. Добавьте режим «пробного запуска», в котором преобразования просто выводятся на стандартный вывод, чтобы вы могли видеть, что произойдет.

  2. Что бы вы ни делали, сначала сделайте резервную копию.

Бонус: я бы, вероятно, использовал для этой работы pathlib и его команды - это более универсальный интерфейс, чем старые методы "имена файлов - просто строки".

...