Пакетное переименование файлов с условной или математической операцией

Это мой первый вопрос здесь. Заранее спасибо.

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

Вот пример:

  • tl0036_20161121-120558.jpg

  • myCode_yyyymmdd_hh mmss.jpg

Я должен поменять символы "чч" 1 час назад, поэтому 12 должно быть 11. Они 17 и 18 позиции. Я представляю два способа сделать это:

  • Математическая операция: изображения берутся с 1 утра до 11 вечера, поэтому я не вижу проблем в выполнении только математической операции, такой как 12-1=11 для всех из них.
  • Условно: если значение 17-го и 18-го символов равно 12, то следует переименовать в 11. Должно быть записано 24 условия, от 01 до 23 начальное значение.

Я нашел много ответов здесь, чтобы заменить / переименовать фиксированную строку и другие об условной операции, но ничего о моем виде смешанной замены.

Пожалуйста, мне нужно сообщить, как скрипт должен предполагать, что он будет выполнен в папке files. Я новичок, привыкший работать с Bash или Python.

Спасибо!

2 ответа

Решение с использованием datetime в Python

import time
import datetime

def change_filename(fn):

    # EXTRACT JUST THE TIMESTAMP AS A STRING
    timestamp_str = fn[7:22]

    # CONVERT TO UNIX TIMESTAMP
    timestamp = time.mktime(datetime.datetime.strptime(timestamp_str, "%Y%m%d-%H%M%S").timetuple())

    # SUBTRACT AN HOUR (3600 SECONDS)
    timestamp = timestamp - 3600

    # CHANGE BACK TO A STRING
    timestamp_str = datetime.datetime.fromtimestamp(timestamp).strftime("%Y%m%d-%H%M%S")

    # RETURN THE FILENAME WITH THE NEW TIMESTAMP
    return fn[:7] + timestamp_str + fn[22:]

Это учитывает возможные изменения в дне, месяце и году, которые могут произойти, если поставить отметку времени обратно на час. Если вы используете 12 часов, а не 24 часа, вы можете использовать строку формата "%Y%m%d-%I%M%S" вместо; см. документы по Python.

Кредит: Преобразование строковой даты в отметку времени в Python и Преобразование строки отметки времени unix в читаемую дату в Python.

Это предполагает, что ваш myCode имеет фиксированную длину, если вы не можете использовать str.split метод вытащить часы после - или если ваши имена файлов имеют неизвестный номер / размещение - s, вы можете посмотреть на использование регулярных выражений, чтобы найти часы и заменить их, используя группы захвата.

В Python вы можете использовать комбинацию glob а также shutil.move просматривать файлы и переименовывать их с помощью этой функции. Возможно, вы захотите использовать регулярное выражение, чтобы убедиться, что вы работаете только с файлами, соответствующими вашей схеме именования, если в каталоге / файлах есть и другие файлы.

Наивное решение

С оговорками о длине myCode и формат имени файла, как указано выше.

Если ваши метки времени используют 24-часовой формат (00-23 часа), вы можете заменить часы, вычтя, как вы говорите, одну; но вы должны будете использовать условные выражения, чтобы убедиться, что 23 в 00 и позаботьтесь о добавлении ведущего нуля к часам меньше 10.

Пример в Python будет:

def change_filename(fn):

    hh = int(fn[16:18])

    if hh == 0:
        hh = 23
    else:
        hh -= 1

    hh = str(hh)

    # ADD LEADING ZERO IF hh < 10
    if len(hh) == 1:
        hh = '0' + hh

    return fn[:16] + str(hh) + fn[18:]

Как указывалось выше, важно помнить, что при таком подходе день не будет перенесен на один день, если час будет 00 и будет изменен на 23, так что вам также придется принять это во внимание. То же самое может случиться и с месяцем, и с годом, и вам придется все это учитывать. Гораздо лучше использовать datetime,

Что касается логики переименования файлов, у вас будут проблемы не только с границами дня, но и с месяцем, годом и високосным годом. Например, если ваше имя файла tl0036_20160101-000558.jpgнужно изменить на tl0036_20151231-230558.jpg, Другой пример: tl0036_20160301-000558.jpg будет tl0036_20160229-230558.jpg,

Создание этой логики с нуля займет очень много времени - но, к счастью, есть datetime модуль в Python, в котором уже есть вся эта логика.

Ваш скрипт должен состоять из следующих шагов:

  1. Итерация по каждому '.jpg' файл в вашей папке.
  2. Попробуйте сопоставить ваше имя файла метки времени для каждого '.jpg'
  3. Извлеките значения метки времени и создайте datetime.datetime объект из этих ценностей.
  4. Вычесть datetime.timedelta объект равен 1 часу от этого datetime.datetime объект, и установите это как свою новую метку времени.
  5. Создайте новое имя файла с новой отметкой времени.
  6. Замените старое имя файла новым.

Вот пример реализации:

import datetime
import glob
import os
import re

def change_timestamps(source_folder, hourdiff = -1):

    file_re = re.compile(r'(.*)_(\d{8}-\d{6})\.jpg')
    for source_file_name in glob.iglob(os.path.join(source_folder, '*.jpg')):
        file_match = file_re.match(source_file_name)
        if file_match is not None:
            old_time = datetime.datetime.strptime(file_match.group(2), "%Y%m%d-%H%M%S")
            new_time = old_time + datetime.timedelta(hours = hourdiff)
            new_file_str = '{}_{}.jpg'.format(file_match.group(1), new_time.strftime("%Y%m%d-%H%M%S"))
            new_file_name = os.path.join(source_folder, new_file_str)
            os.replace(source_file_name, new_file_name)
Другие вопросы по тегам