【Python自动化运维】python操作文件目录

  • 作者:leo__programmer
  • 声明:版权所有,转载请注明出处
  • 收藏:查看更多精彩内容

前言

	在实际开发中,经常需要对文件或者目录进行读取、遍历、修改等操作,目录也称文件夹,用于分层保存文件。通过目录可以分门别类地存放文件。我们也可以通过目录快速找到想要的文件。

1、打开文件

1.1 从文件中读取内容

python提供了一个open()函数,可以打开一个文件读取内容,主要的参数1:文件路径,参数2:打开模式(r读取、w写入),在python交互式模式下可以使用help(open) 打开帮助,查看用法。
**注意:**windows中存路径的文件名,定义字符串存文件名的时候,字符串前面加个r, 避免特殊字符被转义,具体用法为r“文件路径”

# 示例代码
file_name = r"C:\Users\file01.txt"
# 创建文件对象
fobj = open(file_name,mode="r",encoding="UTF-8")     # 为了方便操作 定义一个变量
# 获取数据的方法一
content = fobj.read()		# read()默认读所有
print(content)

# 按行读 通过循环遍历文件内容
for i in fobj:      # i  代表文件中每一行的内容    处理日志
	print(i)
fobj.close()		# 使用结束后不要忘记关闭文件

# 打开文件的另一种写法
with open(file_name,mode="r",encoding="UTF-8") as fobj:
    for i in fobj:
         print(i)

2、OS模块

		在 python 中可以使用使用内置的os模块实现操作文件和目录,能够以简洁高效的方式完成这些操作。常见的操作整理如下:
  • 文件夹操作:包括文件夹的创建、修改(改名/移动),查询(查看、遍历)、删除等。
  • 文件操作:包括文件的创建、修改、读取、删除等。
  • 路径操作:文件夹或文件的路径操作,如绝对路径,文件名与路径分割,扩展名分割等

2.1 获取文件/目录方法

os.walk() 方法是一个简单易用的文件、目录遍历器,可以帮助我们高效的处理文件、目录方面的事情。它直接返回的是一个生成器, 返回的是文件的内存地址,想看到的具体的信息需要循环遍历。

语法格式:os.walk(目录名称)
# 代码示例
import os
directory = r"C:\北京"
resqult = os.walk(directory)
# 循环遍历 返回的是递归目录 每个目录是一个元组数据 0索引是路径 1索引是子目录 2索引是文件名
# 获取文件名循环遍历 使用0索引和2索引做拼接
for i in resqult:
	print(i)
	# 如何拿数据 使用元组下标
	print("目录名称:%s" % i[0])
	print("文件名称:%s" % i[-1])

#	第二种写法 分别定义3个变量 获取元组中3个索引的数据
for i,j,k in resqult:
     print("目录名称:",i)
     print("文件名称:",k)
print(resqult)

2.2 文件重命名

做文件重命名 os模块提供了一个现成的方法 可以用rename()方法

os.rename(源文件,新名)
# 为了避免出错  源文件建议写绝对路径

字符串操作方法示例1、获取某个目录下字符串以.txt结尾的文件 ,方法为字符串.endswith(.txt)。
示例2、字符串替换的方法 字符串.replace(旧,新)

2.3 字符串操作的一些方法

# 示例1
str.endswith(".txt")
# 示例2
 .replace(旧,新)
 # .jpg结尾的文件名加时间   传统的做法 截取   字符串.split(".") 用点分割字符串 根据下标取值后再做拼接
# 如何获取时间  datetime.datetime.now().strftime("%Y-%m-%d))

----------------------------------------python做持久化保存的模块------------------------------------------------------

3、pickle模块

pickle模块的优势,存入取出保持数据类型不变。

# 写入数据
# data_01 = ["1111","2222","22233123"]
# with open(r"e:\\file033",mode="wb") as fobj:
#     pickle.dump(data_01,fobj)
#
# # 读取数据
# with open(r"e:\\file033",mode="rb") as fobj:
#     new_data01 = pickle.load(fobj)
#     print(new_data01)
#     print(type(new_data01))

4、python操作目录文件代码示例

import os
import datetime

directory = r"d:\PycharmProjects\pythonProject\北京"

# 递归获取指定目录下的文件路径
def getFileName(directory):
	# 创建列表 用来储存获取到的文件
    file_list = []
    # 遍历目录
    for dir_name,sub_dir_list,file_name_list in os.walk(directory):
        if len(file_name_list) > 0:	
            for f_name in file_name_list:
            	# 拼接目录和文件名
                full_file_name = dir_name + "\\" + f_name
                file_list.append(full_file_name)
    return file_list

# 文件重命名 .txt ----> .jpg
# 该字符串方法不是一个通用的方法 需要结合实际需求进行替换
def fileRename():
	# 调用遍历目录的方法
    file_list = getFileName(directory)
    for src_file in file_list:
        # 获取.txt结尾的文件
        if src_file.endswith(".txt"):
            new_file = src_file.replace(".txt",".jpg")		# 替换
            os.rename(src_file,new_file)	# 重命名

# 重命名——— 文件名_YYYY_MM_DD。jpg
def fileRenameAddTime():
    file_list = getFileName(directory)
    now = datetime.datetime.now().strftime("%Y_%m_%d")
    for src_file in file_list:
        old_name = src_file.split(".")[0]
        suffix = src_file.split(".")[1]
        new_file = old_name + "_" + now + "." + suffix
        os.rename(src_file,new_file)


if __name__ == '__main__':
    fileRenameAddTime()

5、常用案例

5.1 案例一:统计web UV

def webUV(webLog):
    clientIP_list = []
    with open(webLog, mode="r") as fobj:
        for line in fobj:
            # 取客户端IP
            client_IP = line.split()[0]
            clientIP_list.append(client_IP)
        # 统计各IP次数
        for ip in set(clientIP_list):
            print("客户端地址: %s, 次数: %s" % (ip, clientIP_list.count(ip)))

if __name__ == '__main__':
    web_log_file = input("web日志: ").strip()
    webUV(webLog=web_log_file)

5.1.1 改进案例一:通过re正则模块获取IP地址

import re
def webUVByRegex():
    web_log_file = r"D:\project0218\fileIO\access_log"
    ip_address = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
    # 从文件中获取客户端地址
    ip_list = []
    with open(web_log_file, mode="r") as fobj:
        for line in fobj:
            # 类似于grep,能过滤到数据返回Match Object, 否则返回None
            result = re.search(ip_address, line)
            if result:
                ip_list.append(result.group())

    # IP去重,统计次数
    for ip in set(ip_list):
        print("客户端地址: %s, 访问次数: %s" % (ip, ip_list.count(ip)))

5.2 案例二:获取目录下文件名

import os

# 递归获取目录下所有文件名
def getFileName(directory):
    file_list = []
    for dir_name, sub_dir_list, file_name_list in os.walk(directory):
        # 判断对应的目录下有文件
        if len(file_name_list) > 0:
            for f_name in file_name_list:
                full_file_name = dir_name + "\\" + f_name
                file_list.append(full_file_name)
    return file_list


if __name__ == '__main__':
    file_list = getFileName(r"E:\project0528\北京")
    print(file_list)

5.3 案例三: 文件批量重命名

# 批量文件重命名
def fileRename():
    file_list = getFileName(r"E:\project0528\北京")
    for old_file in file_list:
        # 判断.txt结尾的文件
        if old_file.endswith(".txt"):
            new_file_name = old_file.replace("txt", "sql")
            os.rename(old_file, new_file_name)

5.4 案例四: 文件MD5校验

# 文件MD5校验
def fileMD5(filename):
    md5_tool = hashlib.md5()
    with open(filename, mode="rb") as fobj:
        # 循环读取文件内容
        while True:
            data = fobj.read(4096)
            if data:
                md5_tool.update(data)
            else:
                break
    return md5_tool.hexdigest()



if __name__ == '__main__':
    a = fileMD5(filename=r"E:\project0528\utils\access_log")
    b = fileMD5(filename=r"E:\project0528\utils\test1.txt")
    if a == b:
        print("数据一致")
    else:
        print("数据不一致")

5.5 案例五:对比目录间文件差异

# 检测目录间文件差异
def fileDiff():
    source_directory = r"E:\project0528\北京"
    src_file_list = getFileName(source_directory)
    for src_file in src_file_list:
        # 获取备份目录下的同名的文件
        dest_file = src_file.replace("北京", "backup")
        # 同名的目的文件不存在
        if not os.path.exists(dest_file):
            print("文件【%s】丢失!!!!!!!!" % src_file)
        else:
            # 判断文件内容不一致
            src_file_md5 = fileMD5(src_file)
            dest_file_md5 = fileMD5(dest_file)
            if dest_file_md5 != src_file_md5:
                print("源文件【%s】--------目的文件【%s】------数据不一致!!!!" % (src_file, dest_file))


if __name__ == '__main__':
    fileDiff()

5.6 案例六:实现文件完全备份、增量备份

# 完全备份, 增量备份
import tarfile
from utils import fileManager as fm
import datetime
import pickle

# 完全备份
def fullBackUP():
    source_directory = r"E:\project0528\北京"

    # 创建完全备份压缩包
    tar_file = r"E:\project0528\backup\data_%s.tar.gz" % datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
    tar_obj = tarfile.open(tar_file, mode="w:gz")

    # {"文件名称":"文件MD5"} ,便于后续的增量备份
    file_md5_dict = {}

    # 获取源目录下的所有文件, 添加到压缩包
    src_file_list = fm.getFileName(source_directory)
    for src_file in src_file_list:
        tar_obj.add(src_file)
        # 对文件进行MD5校验,写入字典
        src_file_md5 = fm.fileMD5(src_file)
        file_md5_dict[src_file] = src_file_md5
    tar_obj.close()

    # 将字典持久化保存
    md5_file = r"E:\project0528\backup\md5.file"
    with open(md5_file, mode="wb") as fobj:
        pickle.dump(file_md5_dict, fobj)

# 增量备份
def increBackUP():
    source_directory = r"E:\project0528\北京"

    # 创建增量备份压缩包
    tar_file = r"E:\project0528\backup\data_incre_%s.tar.gz" % datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
    tar_obj = tarfile.open(tar_file, mode="w:gz")

    # 获取完全备份时生成的字典
    md5_file = r"E:\project0528\backup\md5.file"
    with open(md5_file, mode="rb") as fobj:
        file_md5_dict = pickle.load(fobj)

    # 重新遍历源目录下的文件,检测变化
    src_file_list = fm.getFileName(source_directory)
    for src_file in src_file_list:
        # 检测新文件
        if src_file not in file_md5_dict.keys():
            tar_obj.add(src_file)
            # 对新文件进行校验,更新字典
            file_new_md5 = fm.fileMD5(src_file)
            file_md5_dict[src_file] = file_new_md5
        else:
            # 检测文件内容有变化
            file_old_md5 = file_md5_dict.get(src_file)
            file_new_md5 = fm.fileMD5(src_file)
            if file_new_md5 != file_old_md5:
                tar_obj.add(src_file)
                # 更新旧文件的校验码
                file_md5_dict[src_file] = file_new_md5

    # 更新硬盘中的字典文件
    with open(md5_file, mode="wb") as fobj:
        pickle.dump(file_md5_dict, fobj)

if __name__ == '__main__':
    day_of_week = datetime.datetime.now().strftime("%w")
    if day_of_week == "1":
        fullBackUP()
    else:
        increBackUP()

5.7 案例七:多线程检测网段在线主机

import subprocess

def checkPing(ip):
    ping_cmd = "ping -n 1 -w 1 %s" % ip
    null_obj = open("win_null_file", mode="wb")
    ping_result = subprocess.call(ping_cmd, shell=True, stdout=null_obj, stderr=null_obj)
    if ping_result == 0:
        print("主机%s在线!!!!" % ip)

if __name__ == '__main__':
    for i in range(1, 255):
        host_ip = "192.168.102.%s" % i
        checkPing(ip=host_ip)

5.8 改进案例七:多线程检测网段在线主机

import subprocess
import threading

def checkPing(ip):
    null_file = open("null_file", mode="wb")
    ping_cmd = "ping -n 1 -w 1 %s" % ip
    ping_result = subprocess.call(ping_cmd, shell=True, stdout=null_file, stderr=null_file)
    if ping_result == 0:
        print("主机%s在线!!" % ip)
    null_file.close()

if __name__ == '__main__':
    for i in range(1,254):
        ip = "192.168.3.%s" % i
        ping_thread = threading.Thread(target=checkPing, args=(ip,))
        ping_thread.start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值