Как идентифицировать файлы с увеличивающимися номерами и похожей формой имени файла?

У меня есть каталог файлов, некоторые из них файлы изображений. Некоторые из этих файлов изображений представляют собой последовательность изображений. Их можно назвать image-000001.png, image-000002.png и так далее, или, возможно, 001_sequence.png, 002_sequence.png и так далее.

Как мы можем идентифицировать изображения, которые для человека по их именам кажутся вполне очевидными в последовательности? Это означало бы идентификацию только тех имен файлов изображений, которые имеют возрастающие номера и все имеют одинаковую форму имени файла.

Аналогичная часть имени файла не будет предопределена.


person d3pd    schedule 19.08.2015    source источник
comment
Вы можете добавить свой код в вопрос и сделать его хорошим! :)   -  person kasravnd    schedule 19.08.2015
comment
Можете ли вы еще объяснить, что вы хотите? Всегда ли числа будут иметь одинаковое количество цифр? Что вы подразумеваете под именами файлов изображений, которые имеют возрастающие числа? Что делать, если image-000182.png отсутствует? Что значит похожий?   -  person Cyphase    schedule 19.08.2015
comment
Грубый набросок алгоритма: 1) имена файлов grep с шаблоном вида \w*\d+\w*.\w+; 2) заменить часть \d+ на _; 3) сгруппировать файлы, где форма одинакова; 4) проверьте, являются ли числа последовательными   -  person tobias_k    schedule 19.08.2015
comment
@Kasramvd Получить список файлов в каталоге очень просто. Это был шаг сразу после этого, в котором я не был уверен, поэтому, к сожалению, в этом случае не могло быть кода для публикации.   -  person d3pd    schedule 19.08.2015
comment
@Cyphase Сейчас у меня нет очень конкретной задачи, но я столкнулся со многими сценариями, которые выводят файлы с именами файлов, которые имеют разную форму, но все еще заметно последовательны по увеличивающимся числам в их именах файлов. Итак, чтобы ответить на ваши вопросы: числа не всегда должны иметь одинаковое количество цифр. Я имею в виду только файлы изображений, которые, по-видимому, представляют собой последовательности файлов, содержащие непрерывную последовательность чисел. Если бы файл в последовательности файлов отсутствовал, то были бы идентифицированы две последовательности. Я имею в виду подобную форму в обычном человеческом восприятии.   -  person d3pd    schedule 19.08.2015


Ответы (2)


Вы можете использовать регулярное выражение, чтобы файлы соответствовали определенному шаблону, например. .*\d+.*\.(jpg|png) для чего угодно, затем число, затем еще что-нибудь и расширение изображения.

files = ["image-000001.png", "image-000002.png", "001_sequence.png", 
         "002_sequence.png", "not an image 1.doc", "not an image 2.doc", 
         "other stuff.txt", "singular image.jpg"]

import re
image_files = [f for f in files if re.match(r".*\d+.*\.(jpg|png)", f)]

Теперь сгруппируйте эти файлы изображений, заменив номер некоторой общей строкой, например. XXX:

patterns = collections.defaultdict(list)
for f in image_files:
    p = re.sub("\d+", "XXX", f)
    patterns[p].append(f)

В результате patterns

{'image-XXX.png': ['image-000001.png', 'image-000002.png'], 
 'XXX_sequence.png': ['001_sequence.png', '002_sequence.png']}

Точно так же не должно быть слишком сложно проверить, являются ли все эти числа последовательными, но, возможно, в конце концов это и не нужно. Однако обратите внимание, что при этом будут проблемы с различением пронумерованных серий, таких как "series1_001.jpg" и "series2_001.jpg".

person tobias_k    schedule 19.08.2015
comment
Большое спасибо за четкое решение с подробными комментариями. Я добавил естественную функцию сортировки для списков в результирующем словаре, и теперь этот подход отлично работает. - person d3pd; 19.08.2015

Я бы предложил использовать regex файлы корыта и шаблон группового сопоставления со списком связанных номеров из имени файла.

Как только это будет сделано, просто переберите ключи словаря и убедитесь, что количество элементов совпадает с диапазоном совпавших чисел.

import re
from collections import defaultdict
from os import listdir

files = listdir("/the/path/")

found_patterns = defaultdict(list)
p = re.compile("(.*?)(\d+)(.*)\.png")

for f in files:
    if p.match(f):
        s = p.search(f)
        pattern = s.group(1) + "___" + s.group(3)
        num = int(s.group(2))
        found_patterns[pattern].append(num)

for pattern, found in found_patterns.items():
    mini, maxi = min(found), max(found)
    if len(found) == maxi - mini + 1:
        print("Pattern correct: %s" % pattern)

Конечно, это не сработает, если есть какое-то пропущенное значение, но вы можете использовать некоторую ошибку принятия.

person Delgan    schedule 19.08.2015
comment
Большое спасибо за эффективное решение. Это помогло мне узнать о регулярных выражениях. - person d3pd; 19.08.2015