Python argparse模块实现模拟 linux 的ls命令

python 模拟linux的 ls 命令

sample: python custom_ls.py -alh c:/

选项:

-a ,--all 显示所有文件,包括'.'开头的隐藏文件

-l  列表显示每个文件详细信息

-h 以人类可读的方式显示,文件大小会被换算成 K、M、G、T 或 P 的单位

path

只能接受一个path路径,需要改进。

from pathlib import Path
import argparse
import datetime
import stat
import os


def convert_mode(mode: int):
    modelist = ['r', 'w', 'x', 'r', 'w', 'x', 'r', 'w', 'x']
    m = mode & 0o777
    modestr = bin(m)[-9:]
    ret = ""
    for i, v in enumerate(modestr):
        if v == '1':
            ret += modelist[i]
        else:
            ret += '-'
    return ret


def convert_type(file: Path):
    ret = ""
    if file.is_symlink():
        ret = 'l'
    elif file.is_fifo():
        ret = 'p'
    elif file.is_socket():
        ret = 's'
    elif file.is_block_device():
        ret = 'b'
    elif file.is_char_device():
        ret = 'c'
    elif file.is_dir():
        ret = 'd'
    elif file.is_file():
        ret = '-'
    else:
        ret = '?'
    return ret


def list_dir(path: str = '.', all=False, detail=False, human=False):
    units = ['', 'K', 'M', 'G', 'T', 'P']

    def _convert_human(size: int):
        depth = 0
        while size >= 1024:
            size = size // 1024
            depth += 1
        return "{}{}".format(size, units[depth])

    def _show_dir(path: str = '.', all=False, detail=False, human=False):
        p = Path(path)
        for file in p.iterdir():
            if not all and str(file.name).startswith('.'):
                continue

            if detail:
                st = file.stat()

                h = st.st_size
                if human:
                    h = _convert_human(st.st_size)

                owner, group = st.st_uid, st.st_gid
                if os.name == "posix":
                    owner, group = file.owner(), file.group()

                yield str((stat.filemode(st.st_mode), st.st_nlink, owner, group, str(h),
                           datetime.datetime.fromtimestamp(st.st_atime).strftime('%Y-%m-%d %H:%M:%S'),
                           file.name)).strip(
                    '()')
            else:
                yield str((file.name,)).strip('()')

    yield from sorted(_show_dir(args.path, args.all, args.l, args.h), key=lambda x: x[-1])


parser = argparse.ArgumentParser(prog='ls', add_help=False, description='list directory contents. --20171031')
parser.add_argument('path', nargs='?', default='.', help='give a path (files or direction)')
parser.add_argument('-l', action='store_true', help='List Display details')
parser.add_argument('-h', action='store_true', help='Human readable way to show "kmgtp" size')
parser.add_argument('-a', '--all', action='store_true', help='Show hidden files at the same time')

if __name__ == '__main__':
    args = parser.parse_args(('.', '-ahl'))
    parser.print_help()
    print('args=', args)

    for st in list_dir(args.path, args.all, args.l, args.h):
        print(st)

  

原文地址:https://www.cnblogs.com/i-honey/p/7763358.html