Пакетное переименование файлов с условной или математической операцией
Это мой первый вопрос здесь. Заранее спасибо.
Я автоматически загрузил сотни изображений на сервер 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, в котором уже есть вся эта логика.
Ваш скрипт должен состоять из следующих шагов:
- Итерация по каждому
'.jpg'
файл в вашей папке. - Попробуйте сопоставить ваше имя файла метки времени для каждого
'.jpg'
- Извлеките значения метки времени и создайте
datetime.datetime
объект из этих ценностей. - Вычесть
datetime.timedelta
объект равен 1 часу от этогоdatetime.datetime
объект, и установите это как свою новую метку времени. - Создайте новое имя файла с новой отметкой времени.
- Замените старое имя файла новым.
Вот пример реализации:
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)