Python运维(一)--路径、文件及文件夹

一、文件及文件夹增删改查

1.1 常规操作

  • 代码示例
    import os
    
    # 显示系统默认路径分隔符:win10为'\\'
    os.sep
    >>> '/'
    # pwd命令:获取当前所在路径
    os.getcwd()
    # win10:'E:\\code\\test'
    >>>'/root'
    # cd命令:修改工作路径,无返回值
    #        不存在报错FileNotFoundError
    os.chdir("/home")
    # ls 命令
    # 无参数:显示当前工作目录下文件列表
    # 有参数:指定路径下的文件列表,
    #		 不存在报错FileNotFoundError
    os.listdir()
    >>>  ['sam', 'smith', 'base.py']
    # mkdir命令:如果已存在,报错FileExistsError
    os.mkdir("duke")
    
    import shutil
    
    # 复制文件:当前文件夹内
    shutil.copy("base.py","base_backup.py")
    >>> 'base_backup.py'
    # 复制文件到文件夹内:可以写绝对路径,相对路径
    shutil.copy("base.py","duke")
    >>> 'duke/base.py'
    
    # 复制文件夹:第二个为路径,若不存在会递归创建
    # 若存在,则报错FileExistsError
    shutil.copytree("duke","duke_backup")
    >>> 'duke_backup'
    
    # move命令:移动和重命名,同父文件夹则重命名,文件和文件夹都可以
    shutil.move("base_backup.py", "base_back.py")
    >>> 'base_back.py'
    
    # rm -rf 目录:删除目录
    shutil.rmtree("duke_backup")
    # 删除文件
    os.remove("base_back.py")
    

1.2 权限操作

  • 代码示例
    import os
    os.listdir()
    >>> ['123.py']
    # 查看文件权限:W_OK可写、R_OK可读,X_OK可执行
    os.access('123.py', os.R_OK)
    >>> True
    
    # 获取文件所有者uid:在文件/etc/password内
    os.stat('123.py').st_uid
    >>> 0
    # 获取文件所有组gid:在文件/etc/password内
    os.stat('123.py').st_gid
    >>> 0
    
    # 修改权限:十进制不能以0开头
    os.chmod('123.py', 0o700)
    
    

二、遍历文件夹

  • os.walk实现
    # os.walk()返回的是生成器: 可以写相对路径:"."、"duke",与下效果同
    for dirpath,dirnames,filenames in os.walk("/home/duke"):
         print(dirpath)
         print(dirnames)
         print(filenames)
         # 以上为第一轮遍历:
    
    # 当前遍历的文件夹名
    /home/duke
    # 子文件夹名列表
    ['base']
    # 子文件名列表
    ['base.py']
    
    # 同第一个遍历
    /home/duke/base
    ['subdir']
    ['a.py', 'b.py']
    
    # 同第一个遍历
    /home/duke/base/subdir
    []
    []
    
  • 定制化遍历文件夹
    import os
    import re
    
    
    def is_file_match(filename, patterns):
        # 遍历规则
        for pattern in patterns:
            # 匹配文件名和规则:如果不匹配则为[]
            if re.findall(pattern, filename):
                return True
        return False
    
    
    # 此为一个生成器:因为含有yield语句
    def find_specific_files(root, patterns=[r'.*'], exclude_dirs=[]):
        # 遍历传入的路径root
        for root, dirnames, filenames in os.walk(root):
            # 进行文件名正则匹配
            for filename in filenames:
                # 调用上一个函数进行匹配
                if is_file_match(filename, patterns):
                    # 抛出符合条件的拼接路径
                    yield os.path.join(root, filename)
            # 进行例外文件夹刨除:每一轮都刨除一遍
            for d in exclude_dirs:
                if d in dirnames:
                    dirnames.remove(d)
    
    
    if __name__ == '__main__':
        # 正则写后缀名
        patterns = [r'.*\.xml$', r'.*\.py$']
        exclude_dirs = ['venv']
        # 方法一:生成器配合列表生成式
        filelist = [item for item in find_specific_files(".", patterns, \
        												exclude_dirs)]
        # 方法二:迭代遍历生成器
        for i in find_specific_files(".", patterns, exclude_dirs):
            print(i)
    

三、路径操作

3.1 路径判断

  • 代码示例
    import os
    
    # 以下均返回布尔值
    # 文件判断:不存在也为False
    os.path.isfile("base")
    # 文件夹判断:不存在也为False
    os.path.isdir("base")
    # 快捷方式判断:ln -s 命令生成的
    os.path.islink("base")
    # 挂载点判断:centos7可以通过df命令查看
    os.path.ismount("base")
    # 指定路径(文件或文件夹)存在与否判断
    os.path.exists("./base")
    # 绝对路径判断:不判断是否存在
    os.path.isabs("/root/base")
    

3.2 路径解析

  • 代码示例
    # 获取指定相对路径的绝对路径:等同'base'
    os.path.abspath('./base')
    >>>'/home/duke/base'
    # 获取展开用户家目录:不判断是否存在
    os.path.expanduser("~/home")
    >>> '/root/home'
    # 获取父目录:不管test是文件还是文件夹,不判断是否存在
    os.path.dirname("/root/base/test")
    >>> "/root/base"
    

3.3 路径拼接

  • 代码示例
    # 分离文件名和扩展名
    os.path.splitext('/root/base.py')
    >>> ('/root/base', '.py')
    # 返回父目录与子元素:不判断路径是否存在
    os.path.split('/root/base/base.py')
    >>> ('/root/base', 'base.py')
    # 连接父目录与子元素:不判断路径是否存在,使用os.sep分隔符
    os.path.join("/root/base","base.py")
    >>> '/root/base/base.py'
    

四、组合语句

4.1 查找当前目录下的py文件

  • 代码示例
    import os
    # 写法一
    [item for item in os.listdir() \
    if os.path.isfile(item) \
    and os.path.splitext(item)[1]=='.py']	
    
    # 写法二
    [item for item in os.listdir() if item.endswith('.py')]
    
    # 写法三:记住这个就行了,复杂匹配用列表生成式和re模块
    import glob
    # 默认获取当前工作目录下的文件,可用os.chdir(r'/mnt/main')修改
    # 或在路径中直接写入
    # glob.glob(r‘/mnt/main/*.py’),此时返回的列表每个是绝对路径
    glob.glob(r'*.py')
    
    # 以上三个返回结果均如下
    >>>['apis.py', 'config.py']
    

4.2 获取文件夹下文件大小的字典

  • 代码示例
    import os
    
    {item: os.path.getsize(item) for item in os.listdir() \
    							 if os.path.isfile(item)}
    # 返回字典:字节数
    >>> {'123.py': 17, '345.text': 0, '234.doc': 28}
    

五、文件操作

5.1 文件时间、大小

  • 代码示例
    import os
    
    # 获取文件 时间戳
    # 创建时间:create
    os.path.getctime("123.py")
    >>> 1654673213.4272797
    # 修改时间:modify
    os.path.getmtime("123.py")
    >>> 1654673213.4272797
    # 访问时间:access
    os.path.getatime("123.py")
    >>> 1654673213.4272797
    
    # 获取 文件大小:字节,文件不存在OSError
    os.path.getsize('base')
    >>> 336
    

5.2 文件比较

  • 代码示例
    import filecmp
    # 比较两个文件二进制内容是否相同
    filecmp.cmp("123.py", "345.py")
    >>> True
    
    # 比较两个文件夹的一级目录文件
    d = filecmp.dircmp("a", "b")
    
    d.report()
    >>> diff a b
    >>> Only in a : ['123.py']
    >>> Only in b : ['345.py']
    >>> Identical files : ['234.py']
    # 四个变量
    d.left_only
    d.left_list
    d.right_only
    d.right_list
    

5.3 获取文件的md5值

  • 代码示例
    # 文件名:getfilemd5.py
    import hashlib
    import sys
    
    # 以生成器方式:每次从文件提取8192个字节返回
    def get_chuck(filename):
        with open(filename) as f:
            while True:
                chunk = f.read(8192)
                if not chunk:
                    break
                else:
                    yield chunk
    
    # 读取完全部文件:提取md5校验码
    def get_file_checksum(filename):
        h = hashlib.md5()
        for chunk in get_chuck(filename):
            h.update(chunk.encode("utf8"))
        return h.hexdigest()
    
    if __name__ == '__main__':
        # 此方法为命令行方式使用
        sys.argv.append("")
        print(get_file_checksum(sys.argv[1]))
    #########################################
    #				使用方法					#
    #########################################
    
    # 方法一:以命令行方式获取test.py的md5值
    # 等价 md5sum test.py
    python3 getfilemd5.py test.py
    >>> 4761b856c5dccbad879134690c864d28
    # 在程序中直接调用函数
    get_file_checksum("test.py")
    >>> '4761b856c5dccbad879134690c864d28'
    

5.4 压缩文件

  • zip及bz2格式
    import shutil
    
    # 获取支持的压缩文件格式
    shutil.get_archive_formats()
    >>> [('bztar', "bzip2'ed tar-file"),
    >>> ('gztar', "gzip'ed tar-file"),
    >>> ('tar', 'uncompressed tar file'),
    >>> ('xztar', "xz'ed tar-file"),
    >>> ('zip', 'ZIP file')]
    
    ##############################################
    # 创建压缩文件
    #	压缩文件名(在当前工作目录创建)
    #	压缩文件格式:bztar、zip常用
    #	需要压缩的文件夹
    shutil.make_archive("test", 'zip', './a')
    >>> '/main/a.zip'
    shutil.make_archive("test", 'bztar', './a')
    >>> '/main/test.tar.bz2'
    
    ##############################################
    # 查看压缩文件
    # 查看bz2压缩文件
    import tarfile
    f = tarfile.open('test.tar.bz2', 'r:bz2')
    f.getnames()
    >>>  ['.', './123.py', './234.py']
    
    # 查看zip压缩文件
    import zipfile
    z = zipfile.ZipFile("test.zip", "r")
    for filename in z.namelist():
    	print(filename)
    >>> 234.py
    >>> 123.py
    
    ##############################################
    # 解压缩:
    #	压缩文件的路径(不写绝对路径则相对当前工作目录)
    #	解压到的目录(覆盖式创建,只覆盖同名,不写则为'.')
    # 	解压格式:默认按后缀名自动判断
    shutil.unpack_archive('test.tar.bz2', './test')
    shutil.unpack_archive('./main/test.zip', './code/test')
    
  • rar格式(解压缩测试失败)
    # 需要pip3 install rarfile
    import rarfile
    # 构建rar对象
    rf = rarfile.RarFile('test.rar')
    # 获取rar内文件列表
    rf.namelist()
    >>> ['test/', 'test/123.py', 'test/234.py']
    # 解压缩:解压缩的目标文件夹,若无参数,则在当前文件夹创建test文件
    # 测试失败:
    # 	官网软件下载:https://www.rarlab.com/rar_add.htm
    #	官网教程:https://python-unrar.readthedocs.io/en/v0.3/rarfile.html
    rf.extractall('./a')
    

回到总目录

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值