使用条件或数学运算重命名文件名重命名

时间:2016-11-21 12:16:25

标签: python bash conditional batch-rename webfaction

这是我的第一个问题。提前谢谢。

我已经自动将数百张图片上传到Webfaction服务器,文件名中的时间戳不正确,现在我必须重命名。

以下是一个例子:

  
      
  • tl0036_20161121-的 12 0558.jpg

  •   
  • myCode_yyyymmdd_的 HH mmss.jpg

  •   

我必须在1小时后更改“hh”字符,所以12应该是11.它们是第17和第18位。我想象有两种方法:

  • 数学运算:图像是从凌晨1点到晚上11点拍摄的,所以我认为只进行12-1 = 11的数学运算没有问题。
  • 条件:如果第17个和第18个字符值为12,则重命名为11.应写入24个条件,从01到23的起始值。

我在这里找到了许多答案来替换/重命名一个固定字符串和其他有关条件操作的答案,但没有关于我的那种混合替换。

我需要建议脚本应该,假设它将被执行到files文件夹中。我是一个习惯使用 bash或python 的新手。

谢谢!

2 个答案:

答案 0 :(得分:0)

在Python中使用datetime的解决方案

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 docs

感谢:Convert string date to timestamp in PythonConverting unix timestamp string to readable date in Python

这假设您的myCode具有固定长度,如果不是,您可以使用str.split方法从-之后提取小时数,或者如果您的文件名具有-的未知号码/位置,您可以使用regular expressions查找小时数,replace使用capturing groups查看小时数。{/ p>

在Python中,您可以使用globshutil.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,则此方法不会将日期返回到1,因此您也必须考虑到这一点。月份和年份也可能发生同样的情况,您必须将这些全部考虑在内。使用datetime会更好。

答案 1 :(得分:0)

对于文件重命名逻辑,您不仅会遇到跨越边界的问题,还会遇到月,年和闰年边界问题。例如,如果您的文件名为tl0036_20160101-000558.jpg,则需要更改为tl0036_20151231-230558.jpg。另一个例子:tl0036_20160301-000558.jpg将为tl0036_20160229-230558.jpg

从头开始创建这个逻辑非常耗时 - 但幸运的是,Python中的datetime模块已经内置了所有这些逻辑。

您的脚本应包含以下步骤:

  1. 遍历文件夹中的每个'.jpg'文件。
  2. 尝试匹配每个'.jpg'
  3. 的时间戳文件名
  4. 提取时间戳值并从这些值中创建datetime.datetime个对象。
  5. 从该datetime.timedelta对象中减去等于1小时的datetime.datetime个对象,并将其设置为新的时间戳。
  6. 使用新时间戳构建新文件名。
  7. 用新文件名替换旧文件名。
  8. 以下是一个示例实现:

    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)