пакетное переименование файлов 100K с помощью python
у меня есть папка с более чем 100 000 файлов, все пронумерованы с тем же заглушкой, но без ведущих нулей, и номера не всегда смежны (обычно они есть, но есть пробелы) e.g:
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,
etc.
Я хотел бы пакетно обработать это, чтобы создать дополненные, непрерывные файлы. е.г:
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,
etc. тогда
file-2,
file-2x,
file-2xx,
etc. Как я могу заставить его пройти в порядке числового значения? Я полный python noob, но, глядя на документы, я предполагаю, что могу использовать map для создания нового списка, отфильтровывая только числовую часть, а затем сортировать этот список, а затем повторять это? С более чем 100K файлами это может быть тяжело. Любые советы приветствуются!
6 ответов
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,...) проложенный, как вы хотите, в месте назначения-имя.
есть три шага. Первый-получить все имена файлов. Второй-преобразование имен файлов. Третий-переименование.
если все файлы находятся в одной папке, то 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)
спасибо всем за ваши предложения, я постараюсь их все, чтобы узнать различные подходы. Решение, которое я выбрал, основано на использовании естественной сортировки в моем списке файлов, а затем повторении этого для переименования. Это был один из предложенных ответов, но по какой-то причине он исчез, поэтому я не могу отметить его как принятый!
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/
Почему бы вам не сделать это в два этапа. Проанализируйте все файлы и переименуйте их с помощью добавленных номеров, а затем запустите другой скрипт, который возьмет эти файлы, которые теперь отсортированы правильно, и переименует их, чтобы они были смежными?
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"
надеюсь, что это помогает