需求】
- 真实项目经历:某一个目录(示例中为:services这个目录)下面有很多文件,包括文件和目录,这些目录下面有一个名称一样的配置文件(有些目录下面不一定有这个文件),我们现在要批量修改这个文件里面的某个字符串。
- 思路分析:
- 首先要获取所有的目录,并检查这些目录下面是否包含目标配置文件;
- 修改目标字符串;
- 检查字符串修改是否成功。
这里我是新创建了一些文件和目录作为演示,源文件目录比这要复杂,需要修改的目录情况如下:
[root@tencent services]# ll
总用量 12
-rw-r--r-- 1 root root 0 9月 20 14:04 1.txt
-rw-r--r-- 1 root root 0 9月 20 14:04 2.txt
-rw-r--r-- 1 root root 0 9月 20 14:04 3.txt
-rw-r--r-- 1 root root 0 9月 20 14:04 4.txt
-rw-r--r-- 1 root root 0 9月 20 14:04 5.txt
-rw-r--r-- 1 root root 0 9月 20 14:04 6.txt
-rw-r--r-- 1 root root 0 9月 20 14:04 7.txt
-rw-r--r-- 1 root root 0 9月 20 14:04 8.txt
drwxr-xr-x 4 root root 4096 9月 20 16:57 docker
drwxr-xr-x 2 root root 4096 9月 20 11:38 mysql
drwxr-xr-x 4 root root 4096 9月 20 16:49 nginx
脚本:
proj/
├── abtainDir.py # 用来获取项目目录下面所有的目录名称
├── check.py # 用来检查修改的结果
├── existStr.py # 查看是否存在nginx.conf文件,该文件中是否存在我们要的字符串,如果存在就修改
├── main.py # 主函数,调用abtainDir、existStr和modify模块
├── modify.py # 修改字符串
代码如下:
(1)abtainDir.py
import os
# 只获取项目目录下面所有的目录名称
# 项目目录和它下面要修改的两个目录: docker和nginx,因为mysql下面没有目标文件nginx.conf
"""
[root@tencent services]# ls
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt docker mysql nginx
"""
# 项目路径,所有的目录都在这一个路径下面
projPath = '/root/python/project/proj1/sourcefile/services'
# 存放获取到的目录的名称
dir_list = []
def dirName():
dirname = os.listdir(projPath)
os.chdir(projPath)
# 只获取目录的名称
for i in dirname:
if os.path.isdir(i):
dir_list.append(i)
return dir_list
(2)modify.py
import os
import re
# 修改字符串
# filePath: 就是nginx.conf的绝对路径
def alterStr(filePath, old_str, new_str):
print('开始修改文件 {}'.format(filePath))
with open(filePath, 'r', encoding='utf-8') as f1, open("%s.bak" % filePath, 'w', encoding='utf-8') as f2:
for line in f1:
f2.write(re.sub(old_str, new_str, line))
os.remove(filePath)
os.rename("%s.bak" % filePath, filePath)
(3)existStr.py
import os
import abtainDir
import modify
# 筛选出包含目标字符串的项目
projPath = '/root/python/project/proj1/sourcefile/services/'
# 存放包含nginx.conf的目录
existFile = []
# 判断目录中是否存在目标配置文件:nginx.conf
def fileExist():
dname = abtainDir.dirName()
for name in dname:
filePath = projPath + name + '/nginx.conf'
if os.path.exists(filePath):
existFile.append(filePath)
return existFile
# 判断配置文件中是否存在目标字符串:worker_connections 4096;
# 如果包含则调用modify模块修改目标字符串
def strExist():
old_str = '4096'
new_str = '8192'
fpath = fileExist()
for file in fpath:
f = open(file, 'r')
lines = f.readlines()
for line in lines:
if old_str in line:
modify.alterStr(file, old_str, new_str)
f.close()
(4)main.py
import existStr
# 调用fileExist()判断nginx.conf是否存在;
# 调用strExist()判断字符串是否存在,如果存在就开始修改
def main():
existStr.fileExist()
existStr.strExist()
main()
(5)checkStr.py
import existStr
# 判断字符串是否已经修改成功
fileList = []
def check():
str1 = 'worker_connections 8192'
fileList = existStr.fileExist()
for i in fileList:
f = open(i, 'r')
for line in f.readlines():
if str1 in line:
print("修改成功: {}".format(i))
f.close()
if __name__ == '__main__':
print('开始检查文件修改是否成功')
check()
总结:
(1)这个脚本有一个缺点,就是修改的字符串必须要是唯一的,就是在nginx.conf中必须是唯一的;
(2)整体感受,在处理文本方面,python没有awk、sed和grep命令用着顺手。