Как изменить имена папок в python?

У меня есть несколько папок с именем человека, с первым именем (именами) и фамилией последним. Я хочу изменить имена папок, чтобы сначала была фамилия, затем запятая, а затем первое имя (имена).

Например, в папке Test у меня есть:

C:/Test/John Smith
C:/Test/Fred Jones
C:/Test/Ben Jack Martin

и я хочу это сделать:

C:/Test/Smith, John
C:/Test/Jones, Fred
C:/Test/Martin, Ben Jack

Я пробовал некоторые вещи с os.rename, но я не мог заставить его работать с переменной длиной имени, и я не знал, как вставить запятую в фамилию.

Кроме того, некоторые имена папок уже находятся в правильной форме, поэтому мне нужно пропустить эти папки во время переименования. Я думаю, вы можете сделать это, просто добавив if, так что если имя папки содержит запятую, оно будет продолжено.

В противном случае фамилия всегда будет последним словом в имени папки.

Спасибо за любую помощь, которую вы можете предоставить.

Ответ 1

Вы можете записать его довольно прямолинейно, используя функции os.listdir и os.path:

import os
basedir = 'C:/Test'
for fn in os.listdir(basedir):
  if not os.path.isdir(os.path.join(basedir, fn)):
    continue # Not a directory
  if ',' in fn:
    continue # Already in the correct form
  if ' ' not in fn:
    continue # Invalid format
  firstname,_,surname = fn.rpartition(' ')
  os.rename(os.path.join(basedir, fn),
            os.path.join(basedir, surname + ', ' + firstname))

Ответ 2

os.rename("Joe Blow", "Blow, Joe")

Кажется, все в порядке. С какой частью у вас проблемы?

Ответ 3

Мне нравится phihag предложение rpartition(), я думаю, что следующие в основном эквивалентны:

>>> 'first second third fourth'.rpartition(' ')
('first second third', ' ', 'fourth')
>>> 'first second third fourth'.rsplit(None, 1)
['first second third', 'fourth']

Я предпочитаю rsplit() потому что я не хочу заботиться о разделителе, но я также вижу, что он немного более подробный.

Настроить

>>> base = 'C:\\Test'
>>> os.makedirs(os.path.join(base, 'John Smith'))
>>> os.makedirs(os.path.join(base, 'Fred Jones'))
>>> os.makedirs(os.path.join(base, 'Ben Jack Martin'))
>>> os.listdir(base)
['Ben Jack Martin', 'Fred Jones', 'John Smith']

Решение

>>> for old_name in os.listdir(base):
    # [::-1] is slice notation for "reverse"
    new_name = ', '.join(old_name.rsplit(None, 1)[::-1])
    os.rename(os.path.join(base, old_name),
          os.path.join(base, new_name))


>>> os.listdir(base)
['Jones, Fred', 'Martin, Ben Jack', 'Smith, John']