使用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 相关文章推荐
python比较2个xml内容的方法
May 11 Python
Python中利用sqrt()方法进行平方根计算的教程
May 15 Python
深入浅析ImageMagick命令执行漏洞
Oct 11 Python
Python基于贪心算法解决背包问题示例
Nov 27 Python
python下载微信公众号相关文章
Feb 26 Python
基于腾讯云服务器部署微信小程序后台服务(Python+Django)
May 08 Python
简单了解Python matplotlib线的属性
Jun 29 Python
Django stark组件使用及原理详解
Aug 22 Python
Django 实现将图片转为Base64,然后使用json传输
Mar 27 Python
Python 私有属性和私有方法应用场景分析
Jun 19 Python
python 邮件检测工具mmpi的使用
Jan 04 Python
Python线程池与GIL全局锁实现抽奖小案例
Apr 13 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
第七节--类的静态成员
2006/11/16 PHP
codeigniter框架批量插入数据
2014/01/09 PHP
PHP调试函数和日志记录函数分享
2015/01/31 PHP
php ajax实现文件上传进度条
2016/03/29 PHP
让你的PHP7更快之Hugepage用法分析
2016/05/31 PHP
PHP打印输出函数汇总
2016/08/28 PHP
php 二维数组时间排序实现代码
2016/11/19 PHP
JavaScript 通过模式匹配实现重载
2010/08/12 Javascript
JS中不为人知的五种声明Number的方式简要概述
2013/02/22 Javascript
兼容ie、firefox的图片自动缩放的css跟js代码分享
2013/08/12 Javascript
js onload事件不起作用示例分析
2013/10/09 Javascript
深入理解Javascript中的循环优化
2013/11/09 Javascript
ff下JQuery无法监听input的keyup事件的解决方法
2013/12/12 Javascript
14个有用的Jquery技巧分享
2015/01/08 Javascript
异步安全加载javascript文件的方法
2015/07/21 Javascript
JavaScript学习小结(一)——JavaScript入门基础
2015/09/02 Javascript
jquery心形点赞关注效果的简单实现
2016/11/14 Javascript
探讨AngularJs中ui.route的简单应用
2016/11/16 Javascript
JS中绑定事件顺序(事件冒泡与事件捕获区别)
2017/01/24 Javascript
基于react框架使用的一些细节要点的思考
2017/05/31 Javascript
AngularJS遍历获取数组元素的方法示例
2017/11/11 Javascript
react中使用swiper的具体方法
2018/05/15 Javascript
vue .sync修饰符的使用详解
2018/06/15 Javascript
Vue.js实现数据响应的方法
2018/08/13 Javascript
react项目实践之webpack-dev-serve
2018/09/14 Javascript
[03:17]2014DOTA2 国际邀请赛中国区预选赛 四强专访
2014/05/23 DOTA
python 实现矩阵上下/左右翻转,转置的示例
2019/01/23 Python
python 去除二维数组/二维列表中的重复行方法
2019/01/23 Python
PyCharm 创建指定版本的 Django(超详图解教程)
2019/06/18 Python
Python fileinput模块如何逐行读取多个文件
2020/10/05 Python
台湾东南旅游社网站:东南旅游
2019/02/11 全球购物
社区党总支书记先进事迹材料
2014/01/24 职场文书
单位承诺书格式
2014/05/21 职场文书
党组织领导班子整改方案
2014/10/25 职场文书
通报表扬范文
2015/01/17 职场文书
放假通知
2015/04/14 职场文书