blog
代码块批量替换
在程序设计中,经常有一些批量代码块(文本)需要替换。如HTLM开发,其导航栏和footer栏,如果网页较少,则可以手动复制相同的代码块。 当网页非常多的时候,如果还这么做无疑是灾难级的维护。现在的javascript管理工具应该是有针对这一问题处理的场景,不过我也不太清楚,没用过。这一想到的第一方法是 把相同的代码另存为文本文件,然后用JavaScript加载。
JavaScript代码形式如下:
这样做的好处是一次编写公用文件,只要在需要加载的地方引入即可。但是也有坏处,有些浏览器不会及时刷新加载的javascrip修改的内容。 另外,在引入一些框架后,容易让以上方法失效,我自己的经验是这样的。不过,也可能是有其他原因,没查出。
这里想到的第二个方法是自己编写代码块替换函数。代码文件名为updateNavfoot.py, 代码如下:
# encoding:utf-8
#!/usr/bin/env python
"""
------------------------------------------ main script
Author : song.yz Copyrigt (C)
Purpose : 2023-2-6 12:22 (V 1.0)
python -m pdb *.py
Email : song.yz@foxmail.com
Copyrigt (C) : Chinese Academy of Sciences
All rights reserved, 2023
-----------------------------------------------------
"""
import sys
import csv
import os
def main(finName,configList):
"""
-----------------------------------------------------
Author : song.yz Copyrigt (C)
Purpose : 2023-2-6 12:22 (V 1.0)
the tag of HTML sample
-----------------------------------------------------
Input parameters :
finName ---- HTML file name which will be update by pubString
pubfileName -- public file name
key word
Output parameters :
----------------------------------------------------
"""
fout = open('new-'+finName,'wt')
fin = open(finName,'rt')
while True :
line = fin.readline()
if not line:
break
lineType,pubfileName = lineInfo(line,configList)
if lineType == 0:
fout.write(line)
if lineType == 1:
ftmp = open(pubfileName,'rt')
strtmp = ftmp.read()
fout.write(line)
#keep the initial tag
fout.write(strtmp)
while True :
line = fin.readline()
if not line:
break
lineType,pubfileName = lineInfo(line,configList)
if lineType == 2:
fout.write('\n'+line)
break
#keep the initial tag
fout.close()
fin.close()
return 0
def lineInfo(line,configList):
"""
-----------------------------------------------------
Author : song.yz Copyrigt (C)
Purpose : 2023-2-7 11:31 (V 1.0)
get the type of a string which is a line of the HTML file
-----------------------------------------------------
Input parameters :
Output parameters :
lineType ---- 0 norm line
1 begin flag
2 end flag
----------------------------------------------------
"""
lineType = 0
lineList = line.split()
pubfileName = 'xx'
if len(lineList) == 3:
for configLine in configList:
configLineList = configLine[0].split()
# split the line to list
if lineList[0] == '':
if lineList[1] == configLineList[0]:
lineType = 1
pubfileName = configLineList[2]
if lineList[1] == configLineList[1]:
lineType = 2
return lineType,pubfileName
def getConfig():
"""
-----------------------------------------------------
Author : song.yz Copyrigt (C)
Purpose : 2023-2-7 12:39 (V 1.0)
read the cvs config file and trans the
string to list
config file sample :
navBegin navEnd navpub.html
footBegin footEnd footpub.html
-----------------------------------------------------
Input parameters :
Output parameters :
----------------------------------------------------
"""
fileConfig = open("config.csv",'rt')
configString = csv.reader(fileConfig)
configList = list(configString)
fileConfig.close()
return configList
def updateFiles():
"""
-----------------------------------------------------
Author : song.yz Copyrigt (C)
Purpose : 2023-2-8 10:17 (V 1.0)
-----------------------------------------------------
Input parameters :
Output parameters :
----------------------------------------------------
"""
currentPath = os.getcwd()
print('currentPath: ' +currentPath)
fin = open("filelist.cfg",'rt')
configList = getConfig()
while True:
line = fin.readline()
if not line:
break
if line[0] == '#':
continue
words = line.split()
filePath = words[0]
fileName = words[1]
os.chdir(filePath)
print("current path"+ os.getcwd())
main(fileName,configList)
os.rename(fileName,fileName+'.bak')
os.rename('new-'+fileName,fileName)
fin.close()
os.chdir(currentPath)
print('currentPath: ' +currentPath)
def deletBakFiles():
"""
-----------------------------------------------------
Author : song.yz Copyrigt (C)
Purpose : 2023-2-8 10:30 (V 1.0)
-----------------------------------------------------
Input parameters :
Output parameters :
----------------------------------------------------
"""
currentPath = os.getcwd()
print('currentPath: ' +currentPath)
fin = open("filelist.cfg",'rt')
while True:
line = fin.readline()
if not line:
break
if line[0] == '#':
continue
words = line.split()
filePath = words[0]
fileName = words[1]
os.chdir(filePath)
print("current path"+ os.getcwd())
if os.path.exists(fileName+'.bak'):
os.remove(fileName+'.bak')
fin.close()
os.chdir(currentPath)
print('currentPath: ' +currentPath)
if __name__=='__main__':
mode = sys.argv[1]
if mode == 'update':
updateFiles()
if mode == 'delete':
deletBakFiles()
以上软件需要配置两个文件,一个是需要更新替换的目标文件列表,因为可以直接处理多目标。文件名为filelist.cfg,文件内容形式如下
/home/astrodynamics/ index0.html ./course index.html ./gradinfo index.html其中第一列为文件路径,第二列为需要替换代码块的目标文件。
第二个文件用来标识目标文件中要替换的内容,和用什么文件替换。其配置文件为config.csv,文件内容形式如下
navBegin navEnd ../pubhtml/nav.html footBegin footEnd ../pubhtml/footer.html
该文件共三列,第一列为替换标识开始关键词,第二列为替换结束关键词。 第三列为公共代码块文本文件。
该程序可以对多个目标替换,可以实现对同一个目标多处替换。 替换使用的命令为
python updateNavfoot.py update
其中update为命令行关键词,用来标识替换更新。在执行改命令后,会在所有原目标文件目录下生成一个后缀为 .bak的备份文件,防止误操作。改文件为替换前的文件。 如果要批量删除备份文件,可以使用
python updateNavfoot.py delete则会删除所有更新操作时产生的备份文件。
文件遍历方法,在python中,可以用os.walk进行文件遍历。在文件很多 情况下,可以先遍历文件然后转到使用以上替换。 代码如下
import os
from os.path import join
def listfiles(homePath):
"""
-----------------------------------------------------
Author : song.yz Copyrigt (C)
Purpose : 2023-2-11 20:02 (V 1.0)
遍历HTML文件
-----------------------------------------------------
Input parameters :
Output parameters :
----------------------------------------------------
"""
for (root,dirs,files) in os.walk(homePath):
for myfile in files:
if myfile[-5:] =='.html':
print(root+' '*5+ myfile)
if __name__=='__main__':
listfiles('./research/')
listfiles('./academics/')
listfiles('./students/')