【Lab】Python改bat文件

时间:2023-03-09 07:19:43
【Lab】Python改bat文件

【Lab】Python改bat文件

给出一个特定的树形结构,每一层的数字依次递增后,按照从上到下,同时从左到右这样的顺序生成。这么说还是不太明白,比如下面这个简单的树形结构。

【Lab】Python改bat文件

按照顺序应该写成这样[3_0, 3_4, 4_1, 4_2]

对应的bat文件内容是这样的。

%%%%%%%%%%%%%%%%[3_0]%%%%%%%%%%%%%%%%
totalLMH2               F:\xdm\test\mainBuilding3\case2\new\[3].jpg    F:\xdm\test\mainBuilding3\case2\new\[0].jpg      F:\xdm\test\mainBuilding3\case2\new\single\QP32\
removeRepeatedCoors     F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
dTAndHP2_1              F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
EnergyOpti_11           F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
perspectiveTAndLumaT    F:\xdm\test\mainBuilding3\case2\new\    F:\xdm\test\mainBuilding3\case2\new\single\QP32\    [3] [0]
jpgToYUV                F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\    F:\xdm\test\mainBuilding3\case2\new\single\QP32\bat\photometricTransfImageYUV\
combine5frames          F:\xdm\test\mainBuilding3\case2\new\yuv\[3].yuv   F:\xdm\test\mainBuilding3\case2\new\yuv\[0].yuv  F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\fiveFramesForHEVCCoding.yuv
HEVC_5Frames         -c QP32_01.cfg -c testPaper.cfg   -i F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\fiveFramesForHEVCCoding.yuv -o F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\recYUV\rec[3_0].yuv > F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\result\result[3_0].txt

%%%%%%%%%%%%%%%%[3]%%%%%%%%%%%%%%%%
HEVC_5Frames        -c  QP32_01.cfg -c testPaper.cfg  -i F:\xdm\test\mainBuilding3\case2\new\yuv\[3].yuv -o F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\recYUV\rec[3].yuv > F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\result\result[3].txt

%%%%%%%%%%%%%%%%3_4%%%%%%%%%%%%%%%%
totalLMH2               F:\xdm\test\mainBuilding3\case2\new\3.jpg    F:\xdm\test\mainBuilding3\case2\new\4.jpg      F:\xdm\test\mainBuilding3\case2\new\single\QP32\
removeRepeatedCoors     F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
dTAndHP2_1              F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
EnergyOpti_11           F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
perspectiveTAndLumaT    F:\xdm\test\mainBuilding3\case2\new\    F:\xdm\test\mainBuilding3\case2\new\single\QP32\    3   4
jpgToYUV                F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\    F:\xdm\test\mainBuilding3\case2\new\single\QP32\bat\photometricTransfImageYUV\
combine5frames          F:\xdm\test\mainBuilding3\case2\new\yuv\3.yuv   F:\xdm\test\mainBuilding3\case2\new\yuv\4.yuv  F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\fiveFramesForHEVCCoding.yuv
HEVC_5Frames         -c QP32_02.cfg -c testPaper.cfg   -i F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\fiveFramesForHEVCCoding.yuv -o F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\recYUV\rec3_4.yuv > F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\result\result3_4.txt

%%%%%%%%%%%%%%%%4_1%%%%%%%%%%%%%%%%
totalLMH2               F:\xdm\test\mainBuilding3\case2\new\4.jpg    F:\xdm\test\mainBuilding3\case2\new\1.jpg      F:\xdm\test\mainBuilding3\case2\new\single\QP32\
removeRepeatedCoors     F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
dTAndHP2_1              F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
EnergyOpti_11           F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
perspectiveTAndLumaT    F:\xdm\test\mainBuilding3\case2\new\    F:\xdm\test\mainBuilding3\case2\new\single\QP32\    4   1
jpgToYUV                F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\    F:\xdm\test\mainBuilding3\case2\new\single\QP32\bat\photometricTransfImageYUV\
combine5frames          F:\xdm\test\mainBuilding3\case2\new\yuv\4.yuv   F:\xdm\test\mainBuilding3\case2\new\yuv\1.yuv  F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\fiveFramesForHEVCCoding.yuv
HEVC_5Frames         -c QP32_02.cfg -c testPaper.cfg   -i F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\fiveFramesForHEVCCoding.yuv -o F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\recYUV\rec4_1.yuv > F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\result\result4_1.txt

%%%%%%%%%%%%%%%%4_2%%%%%%%%%%%%%%%%
totalLMH2               F:\xdm\test\mainBuilding3\case2\new\4.jpg    F:\xdm\test\mainBuilding3\case2\new\2.jpg      F:\xdm\test\mainBuilding3\case2\new\single\QP32\
removeRepeatedCoors     F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
dTAndHP2_1              F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
EnergyOpti_11           F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\
perspectiveTAndLumaT    F:\xdm\test\mainBuilding3\case2\new\    F:\xdm\test\mainBuilding3\case2\new\single\QP32\    4   2
jpgToYUV                F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\    F:\xdm\test\mainBuilding3\case2\new\single\QP32\bat\photometricTransfImageYUV\
combine5frames          F:\xdm\test\mainBuilding3\case2\new\yuv\4.yuv   F:\xdm\test\mainBuilding3\case2\new\yuv\2.yuv  F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\fiveFramesForHEVCCoding.yuv
HEVC_5Frames         -c QP32_03.cfg -c testPaper.cfg   -i F:\xdm\test\mainBuilding3\case2\new\single\QP32\LMH\fiveFramesForHEVCCoding.yuv -o F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\recYUV\rec4_2.yuv > F:\xdm\test\mainBuilding3\case2\new\single\QP32\PWW\result\result4_2.txt

其中被 []括起来的是主要需要修改的地方,第二部分很简单,是根节点(这里是3)。内容结构与其余有点不一样,需要单独处理。

通过观察发现,实际上需要改的地方几乎使用第一行%%%%%%%%%%%%%%%%[\d+_\d+]%%%%%%%%%%%%%%%%里面括起来的编号。处理好其中一部分,其他的for循环就能搞定。写两个函数,一个单独处理根节点部分,另一个处理剩下的部分。

会用到了一个lab_node.bat的模板文件,内容和上面编好的bat几乎一样,读取这个bat文件,用新的数据替换相应部分就好了。共有30部分,若提供的树形结构复杂,超过了30部分,需要自己补充,注意保持QPXX_XX.cfg保持1234的顺序

lab_node.bat文件地址

上面的修改好后,就剩下全局修改了。因为路径不会是\mainBuilding3\case2\new\,得看具体需求,另外case是多图像才有的。最后的最后,将文件里面的QP32替换成QP27QP22生成两个副本。在程序中我使用了w+模式(可读写)打开文件,每次读后需要写或者写后需要读,都需要使用seek(0)将指针定位到文本开头。

这样下来,运行程序就会同时生成三个bat文件了。

import re

# 若树的路径数大于30,请到lab_node.bat增加一些部分。
# 注意每部分的最后一行,QPXX_XX.cfg保持1234的顺序
# 1.从上到下、从左到右,根据排序后的树形图依次填入
l = ('7_9', '7_13', '9_14', '13_3', '13_4', '13_5', '13_6',
     '13_10', '13_11', '13_12', '13_15', '13_16', '13_17')

# 2.填写方法名,层数, reference,多图像的时候填入case
# 单图像路径大概是这样xdm\test\patheon\reference1\
# 多图像路径大概是xdm\test\patheon\case2\reference1\
method, layer, refer, case = 'patheon', '3', 'reference2', ''

# 单图像
if not case:
    file_name = method + '_' + layer + refer + '_'
# 多图像
else:
    file_name = file_name = method + '_' + layer + case + '_' + refer + '_'

def check():
    if len(l) > 30:
        raise Exception('路径数超过30!请到模板文件lab_node.bat下添加缺少的部分')

def split_to_frames():
    """
    输入模板文件,分割成若*分并返回
    :return: 分割好的部分的列表
    """
    # 输入文件
    with open('lab_node.bat', encoding='utf-8') as f:
        # 读取全部内容
        text_plain = f.read()

        # 分成结构相似的多个部分, DOTALL模式'.'匹配任意,包括换行符
        each_frame_p = re.compile(r'%+\d+.*?%+.*?HEVC_5Frames.*?txt', flags=re.DOTALL)
        frames = re.findall(each_frame_p, text_plain)
        return frames

def modify_frame(out_bat, path, frame):
    """
    处理非根节点部分
    :param out_bat: 输出文件
    :param path: 树的路径
    :param frame: 每一部分
    """
    # 处理每个frame的第一行%%%
    line0_p = re.compile(r'%+\d+_\d+%+')
    modify0 = re.sub(line0_p, '%' * 16 + path + '%' * 16, frame)
    # 处理totalLMH2那行,只有该行带有 数字.jpg, 且有两个
    jpg1_p = re.compile(r'totalLMH2.*?\d+.jpg')
    jpg2_p = re.compile(r'jpg.*?\d+.jpg')

    # 第一个数字
    modify1 = re.sub(jpg1_p, r'totalLMH2                F:\\xdm\\test\\mainBuilding3\\new\\'
                     + path.split('_')[0] + '.jpg', modify0)
    # 第二个数字
    modify2 = re.sub(jpg2_p, r'jpg    F:\\xdm\\test\\mainBuilding3\\new\\' + path.split('_')[1] + '.jpg', modify1)
    # .*?为懒惰模式,匹配成功第一个就停止匹配
    # 替换perspectiveTAndLumaT这行末尾的两个数字
    line6_p = re.compile(r'perspectiveTAndLumaT.*?QP\d+\\\s*\d+\s*\d+')
    modify3 = re.sub(line6_p, r'perspectiveTAndLumaT    '
                              r'F:\\xdm\\test\\mainBuilding3\\new\\ '
                              r'F:\\xdm\\test\\mainBuilding3\\new\\single\\QP32\\   ' + path.split('_')[0]
                     + r'   ' + path.split('_')[1],
                     modify2)

    # 替换'.yuv',共3个带数字
    yuv1_p = re.compile(r'frames.*?YUV\\\d+.yuv')
    yuv2_p = re.compile(r'yuv\\\d+.yuv\s*F.*?QP')
    yuv3_p = re.compile(r'-o F.*?rec\d+_\d+')
    modify4 = re.sub(yuv1_p,
                     r'frames           F:\\xdm\\test\\mainBuilding3\\new\\yuv\\' + path.split('_')[0] + '.yuv',
                     modify3)
    modify5 = re.sub(yuv2_p, r'yuv\\' + path.split('_')[0]
                     + r'.yuv   F:\\xdm\\test\\mainBuilding3\\new\\yuv\\' + path.split('_')[1] +
                     r'.yuv  F:\\xdm\\test\\mainBuilding3\\new\\single\\QP', modify4)
    modify6 = re.sub(yuv3_p, r'-o F:\\xdm\\test\\mainBuilding3\\new\\single\\QP32\\PWW\\recYUV\\rec' + path, modify5)
    # 替换'.txt', 共1个带数字
    txt_p = re.findall(r'\d+_\d+.txt', modify6)[0]
    modify7 = re.sub(txt_p, path + '.txt', modify6)
    out_bat.write(modify7 + '\n\n')

def modify_root_frame(out_bat, node, frame1):
    """
    处理根节点部分
    :param out_bat: 输出文件
    :param node: 根节点
    :param frame1: 第一部分
    """
    # 处理每个frame的第一行%%%
    line0_p = re.compile(r'%+\d+%+')
    modify0 = re.sub(line0_p, '%' * 16 + node + '%' * 16, frame1)
    # 替换yuv,共两个,是一样的,选第一个就行
    yuv_p = re.findall(r'\d+.yuv', modify0)[0]
    modify1 = re.sub(yuv_p, node + '.yuv', modify0)
    # 替换txt,共一个
    txt_p = re.findall(r'\d+.txt', modify1)[0]
    modify2 = re.sub(txt_p, node + '.txt', modify1)
    out_bat.write(modify2 + '\n\n')

def replace_all(out_bat):
    """
    替换掉模板文件的路径为当前指定
    :param out_bat: 输出文件
    """
    # 指针在文本末,直接read为空,需要定位到文本开始
    out_bat.seek(0)
    text = out_bat.read()
    # 单图像
    if not case:
        text = re.sub(r'mainBuilding3\\new', method + r'\\' + layer + refer, text)
    # 多图像
    else:
        text = re.sub(r'mainBuilding3\\new', method + r'\\' + case + r'\\' + layer + refer, text)

    # 替换后需要重新写入,由于上面进行过读操作,再将指针指向文本开头,覆盖
    out_bat.seek(0)
    out_bat.write(text)

def create_other_qp(out_bat):
    """
    将QP32替换成QP27和QP22
    :param out_bat: QP32的输出文件
    """
    other_qps = ('27', '22')
    # 刚才覆写了,所以定位到文本开头才能读到
    out_bat.seek(0)
    text = out_bat.read()
    for qp in other_qps:
        with open(file_name + qp + '.bat', 'w', encoding='utf-8') as f:
            new_qp_text = re.sub('QP32', 'QP' + qp, text)
            f.write(new_qp_text)

def run():
    # 检查路径数是否超过30
    check()
    # 第一部分
    first_path = l[0]
    # 根节点
    root = first_path.split('_')[0]
    # 获得所有部分
    frames = split_to_frames()
    with open(file_name + '32.bat', 'w+', encoding='utf-8') as f:
        # 1. 处理第一部分
        modify_frame(f, first_path, frames[0])
        # 2. 再处理根节点部分(第二部分)
        modify_root_frame(f, root, frames[1])
        # 3. 处理余下部分
        # l的index,第一部分处理过了,所以从1开始.
        i = 1
        for frame in frames[2:len(l) + 1]:
            modify_frame(f, l[i], frame)
            i += 1

        # 在全文进行替换
        replace_all(f)
        create_other_qp(f)

if __name__ == '__main__':
    run()

虽然写这个程序的时间用手动改也能完成了。不过下次再给我这种任务,就不大费时间了,根据具体树形结构,修改下列表就行了。


by @sunhaiyu

2017.6.20