пакетное переименование 100K файлов с помощью Python - PullRequest
9 голосов
/ 20 июня 2010

У меня есть папка с более чем 100 000 файлов, все пронумерованы с одной и той же заглушкой, но без начальных нулей, и числа не всегда являются смежными (обычно они есть, но есть пробелы), например:

file-21.png, 
file-22.png,  
file-640.png, 
file-641.png, 
file-642.png, 
file-645.png, 
file-2130.png, 
file-2131.png, 
file-3012.png, 

и т.д.

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

file-000000.png, 
file-000001.png, 
file-000002.png, 
file-000003.png, 

Когда я анализирую папку с for filename in os.listdir('.'):, файлы не отображаются в том порядке, в котором я хотел бы их видеть. Понятно, что они подходят

 file-1, 
 file-1x, 
 file-1xx, 
 file-1xxx,

и т.д.. то

 file-2, 
 file-2x, 
 file-2xx, 

и т.д.. Как я могу заставить это пройти в порядке числового значения? Я полный noob Python, но, глядя на документы, я думаю, я мог бы использовать карту, чтобы создать новый список, отфильтровывая только числовую часть, а затем отсортировать этот список, а затем повторить это? С более чем 100K файлами это может быть тяжело. Любые советы приветствуются!

Ответы [ 6 ]

8 голосов
/ 20 июня 2010
import re
thenum = re.compile('^file-(\d+)\.png$')

def bynumber(fn):
  mo = thenum.match(fn)
  if mo: return int(mo.group(1))

allnames = os.listdir('.')
allnames.sort(key=bynumber)

Теперь у вас есть файлы в нужном вам порядке, и вы можете зациклить

for i, fn in enumerate(allnames):
  ...

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

4 голосов
/ 20 июня 2010

Спасибо всем за ваши предложения, я попробую их все, чтобы изучить различные подходы. Решение, которое я выбрал, основано на использовании естественной сортировки в моем списке файлов, а затем итерации для переименования. Это был один из предложенных ответов, но по какой-то причине он исчез, поэтому я не могу пометить его как принятый!

import os
files = os.listdir('.')
natsort(files)
index = 0
for filename in files:
    os.rename(filename, str(index).zfill(7)+'.png')
    index += 1

где natsort определен в http://code.activestate.com/recipes/285264-natural-string-sorting/

4 голосов
/ 20 июня 2010

Есть три шага.Первый получает все имена файлов.Второе преобразование имен файлов.Третий - их переименование.

Если все файлы находятся в одной папке, то glob должен работать.

import glob
filenames = glob.glob("/path/to/folder/*.txt")

Далее необходимо изменить имя файла.Вы можете напечатать с отступом, чтобы сделать это.

>>> filename = "file-338.txt"
>>> import os
>>> fnpart = os.path.splitext(filename)[0]
>>> fnpart
'file-338'
>>> _, num = fnpart.split("-")
>>> num.rjust(5, "0")
'00338'
>>> newname = "file-%s.txt" % num.rjust(5, "0")
>>> newname
'file-00338.txt'

Теперь вам нужно переименовать их все.os.rename делает именно это.

os.rename(filename, newname)

Чтобы собрать это вместе:

for filename in glob.glob("/path/to/folder/*.txt"): # loop through each file
    newname = make_new_filename(filename) # create a function that does step 2, above
    os.rename(filename, newname)
1 голос
/ 20 июня 2010

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

0 голосов
/ 20 июня 2010
def renamer():
    for iname in os.listdir('.'):
        first, second = iname.replace(" ", "").split("-")
        number, ext = second.split('.')
        first, number, ext = first.strip(), number.strip(), ext.strip()
        number = '0'*(6-len(number)) + number  # pad the number to be 7 digits long
        oname = first + "-" + number + '.' + ext
        os.rename(iname, oname)
    print "Done"

Надеюсь, это поможет

0 голосов
/ 20 июня 2010

1) Возьмите номер в имени файла.2) Левый отступ с нулями 3) Сохранить имя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...