使用Python代码实现Linux中的ls遍历目录命令的实例代码


Posted in Python onSeptember 07, 2019

一、写在前面

前几天在微信上看到这样一篇文章,链接为:https://3water.com/it/692145.html,在这篇文章中,有这样一段话,吸引了我的注意:

使用Python代码实现Linux中的ls遍历目录命令的实例代码

在 Linux 中 ls 是一个使用频率非常高的命令了,可选的参数也有很多, 算是一条不得不掌握的命令。Python 作为一门简单易学的语言,被很多人认为是不需要认真学的,或者只是随便调个库就行了,那可就真是小瞧 Python 了。那这次我就要试着用 Python 来实现一下 Linux 中的 ls 命令, 小小地证明下 Python 的不简单!

二、ls简介

Linux ls 命令用于显示指定工作目录下的内容。语法如下:

ls [-alkrt] [name]

这里只列举了几个常用的参数,ls 命令的可选参数还是很多的,可以使用 man ls 来进行查看具体信息。这里列出的几个参数对应含义如下:

1)-a:显示所有文件及目录;

2)-l:除文件名称外,亦将文件大小、创建时间等信息列出;

3)-k:将文件大小以 KB 形式表示;

4)-r:将文件以相反次序排列;

5)-t:将文件以修改时间次序排列。

三、具体思路

主要使用的模块是 argparse 和 os,其中 argparse 模块能设置和接收命令行参数,也就使得 Python 对命令行的操作变得简单,而 os 模块则用于文件操作,对 argparse 模块不熟悉的可以在这里查看官方文档。

既然要用 Python 实现 ls.py, 也就要在命令行中进行操作,比如 python ls.py -a 这样的命令,而对 Python 比较熟悉的人可能会想到使用 sys 模块来接收输入的命令,但使用 argparse 能让命令行操作变得更加简单!首先要导入模块并创建一个 ArgumentParser 对象,可以理解为一个解析器,然后就可以通过使用 add_argument() 方法为这个解析器添加参数了。示例如下:

# test.py
import argparse
parser = argparse.ArgumentParser(description='Find the maximum number.')
parser.add_argument("integers", type=int, nargs="+", help="The input integers.")
parser.add_argument("-min", nargs="?", required=False, dest="find_num", default=max, const=min, 
      help="Find the minimum number(Default: find the maximum number).")
 
args = parser.parse_args()
print(args)
print(args.find_num(args.Nums))

这段代码的功能是输入一到多个整数,默认求其中的最大值,若有 -min 参数则是求其中的最小值。可以看到在创建解析器和添加命令行参数的时候都设置了 description 描述信息,这个信息会在我们使用 --help 命令的时候显示出来,例如:

使用Python代码实现Linux中的ls遍历目录命令的实例代码

在上面的代码中,需要注意的是其中使用 add_argument() 添加了一个位置参数 "integers" 和一个可选参数 "-min",位置参数在命令行中必须存在,不可遗漏,也就不能设置 required 参数了,而可选参数就不是必须要有的了,因而还可以使用 default 参数设置默认值。nargs 参数用于设置命令行参数的数量,"+" 表示一个或多个,"?" 表示零个或一个,这里由于输入的数字可能有多个,所以要设置为 "+"。最终运行示例如下:

> python test.py 1 3 5

Namespace(find_num=<built-in function max>, integers=[1, 3, 5])
5

> python test.py 1 3 5 -min

Namespace(find_num=<built-in function min>, integers=[1, 3, 5])

1

关于 argparse 的介绍就到此为止了,下面简单介绍下 os 模块, os 模块提供了便捷的使用操作系统相关功能的方式,实现 ls.py 所用到的该模块下的方法包括:

1)os.path.isdir(path):若 path 是一个存在的目录,返回 True。

2)os.listdir(path):返回一个列表,其中包括 path 对应的目录下的内容,不包含“.”和“..”,即使它们存在。

3)os.stat(path):获取文件或文件描述符的状态,返回一个 stat_result 对象,其中包含了各种状态信息。

四、主要代码

ls.py 中的主函数如下,主要功能为创建解析器,设置可选参数和位置参数,然后接收命令行参数信息,并根据输入的参数调用相应的方法,这里设置了一个 "-V" 参数用于显示版本信息,可以使用 "-V" 或者 "-Version" 进行查看。

def main():
  """
  主函数,设置和接收命令行参数,并根据参数调用相应方法
  :return:
  """
  # 创建解析器
  parse = argparse.ArgumentParser(description="Python_ls")
  # 可选参数
  parse.add_argument("-a", "-all", help="Show all files", action="store_true", required=False)
  parse.add_argument("-l", "-long", help="View in long format", action="store_true", required=False)
  parse.add_argument("-k", help="Expressed in bytes", action="store_true", required=False)
  parse.add_argument("-r", "-reverse", help="In reverse order", action="store_true", required=False)
  parse.add_argument("-t", help="Sort by modified time", action="store_true", required=False)
  parse.add_argument("-V", "-Version", help="Get the version", action="store_true", required=False)
  # 位置参数
  parse.add_argument("path", type=str, help="The path", nargs="?")
 
  # 命令行参数信息
  data = vars(parse.parse_args())
  assert type(data) == dict
  if data["V"]:
   print("Python_ls version: 1.0")
   return
  else:
   check_arg(data)

然后是一个获取指定路径下的内容信息的函数,要做的就是判断路径是否存在,若存在就返回一个文件列表,若不存在则显示错误信息,并退出程序。

def get_all(path):
  """
  获取指定路径下的全部内容
  :param path: 路径
  :return:
  """
  if os.path.isdir(path):
   files = [".", ".."] + os.listdir(path)
   return files
  else:
   print("No such file or directory")
   exit()

五、运行结果

下面是 ls.py 运行后的部分结果截图。

首先是 python ls.py -a,这里并没有输入路径,就会使用默认路径即当前目录,如下图:

使用Python代码实现Linux中的ls遍历目录命令的实例代码

然后是 python ls.py -a -t .,使用该命令会显示当前目录下的所有内容,并按照创建的时间进行排序,如下图:

使用Python代码实现Linux中的ls遍历目录命令的实例代码

最后是 python ls.py -a -l -k -r .,也是显示当前目录下的所有内容并按照创建名称排序,不过这次文件大小会以 KB 为单位来显示,如下图:

使用Python代码实现Linux中的ls遍历目录命令的实例代码

到这里为止,ls.py 就算是基本实现了,当然还是有很多可以去实现的功能的,比如更多的参数等等,如果你感兴趣的话可以自己尝试一下==

完整python代码

"""
Version: Python3.7
Author: OniOn
Site: http://www.cnblogs.com/TM0831/
Time: 2019/9/6 21:41
"""
import os
import time
import argparse
import terminaltables


def get(path):
 """
 获取指定路径下的内容
 :param path: 路径
 :return:
 """
 if os.path.isdir(path): # 判断是否是真实路径
  files = os.listdir(path)
  return files
 else:
  print("No such file or directory")
  exit()


def get_all(path):
 """
 获取指定路径下的全部内容
 :param path: 路径
 :return:
 """
 if os.path.isdir(path):
  files = [".", ".."] + os.listdir(path)
  return files
 else:
  print("No such file or directory")
  exit()


def check_arg(data):
 """
 检查参数信息
 :param data: 命令行参数(dict)
 :return:
 """
 assert type(data) == dict
 if not data["path"]:
  data["path"] = "."
 # a参数
 if data["a"]:
  files = get_all(data["path"])
 else:
  files = get(data["path"])
 # r参数
 if data["r"]:
  files = files[::-1]
 # t参数
 if data["t"]:
  files = sorted(files, key=lambda x: os.stat(x).st_mtime)
  for i in range(len(files)):
   files[i] = [files[i], time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(os.stat(files[i]).st_mtime))]
 # l参数
 if data["l"]:
  result = []
  for i in range(len(files)):
   file = files[i][0] if data["t"] else files[i]
   # 获取文件信息
   file_info = os.stat(file)
   # k参数
   if data["k"]:
    # 格式化时间,文件大小用KB表示
    result.append([file, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(file_info.st_ctime)),
        "%.3f KB" % (file_info.st_size / 1024)])
   else:
    # 格式化时间,文件大小用B表示
    result.append([file, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(file_info.st_ctime)),
        "{} Byte".format(file_info.st_size)])
  if data["t"]:
   for i in result:
    i.append(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(os.stat(i[0]).st_mtime)))

  show_file(result, True, True) if data["t"] else show_file(result, True, False)
  return
 show_file(files, False, True) if data["t"] else show_file(files, False, False)


def show_file(files, has_l, has_t):
 """
 格式化输出文件信息
 :param files: 文件列表
 :param has_l: 是否有l参数
 :param has_t: 是否有t参数
 :return:
 """
 # 根据参数信息设置表头
 if not has_l:
  if not has_t:
   table_data = [["ID", "FILE_NAME"]]
   for i in range(len(files)):
    table_data.append([i + 1, files[i]])
  else:
   table_data = [["ID", "FILE_NAME", "FILE_MTIME"]]
   for i in range(len(files)):
    table_data.append([i + 1] + files[i])
 else:
  if not has_t:
   table_data = [["ID", "FILE_NAME", "FILE_CTIME", "FILE_SIZE"]]
  else:
   table_data = [["ID", "FILE_NAME", "FILE_CTIME", "FILE_SIZE", "FILE_MTIME"]]
  for i in range(len(files)):
   table_data.append([i + 1] + files[i])

 # 创建AsciiTable对象
 table = terminaltables.AsciiTable(table_data)
 # 设置标题
 table.title = "file table"
 for i in range(len(table.column_widths)):
  if i != 1:
   # 居中显示
   table.justify_columns[i] = "center"
 print(table.table)


def main():
 """
 主函数,设置和接收命令行参数,并根据参数调用相应方法
 :return:
 """
 # 创建解析器
 parse = argparse.ArgumentParser(description="Python_ls")
 # 可选参数
 parse.add_argument("-a", "-all", help="Show all files", action="store_true", required=False)
 parse.add_argument("-l", "-long", help="View in long format", action="store_true", required=False)
 parse.add_argument("-k", help="Expressed in bytes", action="store_true", required=False)
 parse.add_argument("-r", "-reverse", help="In reverse order", action="store_true", required=False)
 parse.add_argument("-t", help="Sort by modified time", action="store_true", required=False)
 parse.add_argument("-V", "-Version", help="Get the version", action="store_true", required=False)
 # 位置参数
 parse.add_argument("path", type=str, help="The path", nargs="?")

 # 命令行参数信息
 data = vars(parse.parse_args())
 assert type(data) == dict
 if data["V"]:
  print("Python_ls version: 1.0")
  return
 else:
  check_arg(data)


if __name__ == '__main__':
 main()

完整代码已上传到GitHub!

Python 相关文章推荐
Flask框架的学习指南之用户登录管理
Nov 20 Python
Python实现批量读取图片并存入mongodb数据库的方法示例
Apr 02 Python
Python实现随机生成手机号及正则验证手机号的方法
Apr 25 Python
django缓存配置的几种方法详解
Jul 16 Python
实例详解Matlab 与 Python 的区别
Apr 26 Python
Python Opencv任意形状目标检测并绘制框图
Jul 23 Python
Python调用graphviz绘制结构化图形网络示例
Nov 22 Python
PyCharm无法识别PyQt5的2种解决方法,ModuleNotFoundError: No module named 'pyqt5'
Feb 17 Python
Python响应对象text属性乱码解决方案
Mar 31 Python
Python虚拟环境库virtualenvwrapper安装及使用
Jun 17 Python
解决jupyter notebook图片显示模糊和保存清晰图片的操作
Apr 24 Python
Python图像处理库PIL详细使用说明
Apr 06 Python
django创建简单的页面响应实例教程
Sep 06 #Python
如何利用python给图片添加半透明水印
Sep 06 #Python
Python从文件中读取指定的行以及在文件指定位置写入
Sep 06 #Python
Python常用数据类型之间的转换总结
Sep 06 #Python
Python3 JSON编码解码方法详解
Sep 06 #Python
PYTHON EVAL的用法及注意事项解析
Sep 06 #Python
Python实现微信机器人的方法
Sep 06 #Python
You might like
日本十大最佳动漫,全都是二次元的神级作品
2019/10/05 日漫
全国FM电台频率大全 - 22 重庆市
2020/03/11 无线电
PHP中基于ts与nts版本- vc6和vc9编译版本的区别详解
2013/04/26 PHP
php 读取文件头判断文件类型的实现代码
2013/08/05 PHP
javascript编程起步(第六课)
2007/01/10 Javascript
jquery(live)中File input的change方法只起一次作用的解决办法
2011/10/21 Javascript
jquery 提交值不为空的元素示例代码
2013/05/10 Javascript
从QQ网站中提取的纯JS省市区三级联动菜单
2013/12/25 Javascript
使用js如何实现全选与全不选
2013/12/30 Javascript
jquery插件之文字间歇自动向上滚动效果代码
2016/02/25 Javascript
分享jQuery封装好的一些常用操作
2016/07/28 Javascript
async/await与promise(nodejs中的异步操作问题)
2017/03/03 NodeJs
Vue瀑布流插件的使用示例
2018/09/19 Javascript
浅谈微信页面入口文件被缓存解决方案
2018/09/29 Javascript
详解es6新增数组方法简便了哪些操作
2019/05/09 Javascript
在vue中使用cookie记住用户上次选择的实例(本次例子中为下拉框)
2020/09/11 Javascript
javascript实现左右缓动动画函数
2020/11/25 Javascript
JS addEventListener()和attachEvent()方法实现注册事件
2021/01/11 Javascript
[52:32]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第三场 11.18
2020/11/18 DOTA
python利用elaphe制作二维条形码实现代码
2012/05/25 Python
粗略分析Python中的内存泄漏
2015/04/23 Python
简单说明Python中的装饰器的用法
2015/04/24 Python
删除DataFrame中值全为NaN或者包含有NaN的列或行方法
2018/11/06 Python
Python设计模式之组合模式原理与用法实例分析
2019/01/11 Python
Keras构建神经网络踩坑(解决model.predict预测值全为0.0的问题)
2020/07/07 Python
html5手机键盘弹出收起的处理
2020/01/20 HTML / CSS
客户表扬信范文
2014/01/10 职场文书
《识字五》教学反思
2014/03/01 职场文书
关于环保的建议书400字
2014/03/12 职场文书
公司应聘自荐书
2014/06/14 职场文书
2014年酒店服务员工作总结
2014/12/08 职场文书
投标承诺函格式
2015/01/21 职场文书
大学班干部竞选稿
2015/11/20 职场文书
2019银行员工个人工作自我鉴定
2019/06/27 职场文书
浅谈Python项目的服务器部署
2021/04/25 Python
python 单机五子棋对战游戏
2022/04/28 Python