使用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使用rsa加密算法模块模拟新浪微博登录
Jan 22 Python
python使用ctypes模块调用windowsapi获取系统版本示例
Apr 17 Python
Python自动化测试工具Splinter简介和使用实例
May 13 Python
ansible作为python模块库使用的方法实例
Jan 17 Python
Python用imghdr模块识别图片格式实例解析
Jan 11 Python
python format 格式化输出方法
Jul 16 Python
tensorflow 打印内存中的变量方法
Jul 30 Python
python数据结构之线性表的顺序存储结构
Sep 28 Python
Python中三元表达式的几种写法介绍
Mar 04 Python
python2.7 安装pip的方法步骤(管用)
May 05 Python
解决python 找不到module的问题
Feb 12 Python
Pytorch数据读取之Dataset和DataLoader知识总结
May 23 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
解析用PHP实现var_export的详细介绍
2013/06/20 PHP
PHP explode()函数的几个应用和implode()函数有什么区别
2015/11/05 PHP
详解PHP防止直接访问.php 文件的实现方法
2017/07/28 PHP
php使用event扩展的io复用测试的示例
2020/10/20 PHP
用jquery来定位
2007/02/20 Javascript
DOMAssitant最新版 DOMAssistant 2.5发布
2007/12/25 Javascript
FileUpload上传图片(图片不变形)
2010/08/05 Javascript
JavaScript将取代AppleScript?
2014/09/18 Javascript
用Jquery.load载入页面后样式没了页面混乱的解决方法
2014/10/20 Javascript
JavaScript实现的encode64加密算法实例分析
2015/04/15 Javascript
nodejs调用cmd命令实现复制目录
2015/05/04 NodeJs
JS实现的左侧竖向滑动菜单效果代码
2015/10/19 Javascript
JavaScript学习小结之使用canvas画“哆啦A梦”时钟
2016/07/24 Javascript
vue实现可增删查改的成绩单
2016/10/27 Javascript
基于JavaScript实现熔岩灯效果导航菜单
2017/01/04 Javascript
微信小程序新增的拖动组件movable-view使用教程
2017/05/20 Javascript
jQuery实现点击下拉框中的值累加到文本框中的方法示例
2017/10/28 jQuery
详解ES6通过WeakMap解决内存泄漏问题
2018/03/09 Javascript
js中async函数结合promise的小案例浅析
2019/04/14 Javascript
Nuxt配置Element-UI按需引入的操作方法
2020/07/06 Javascript
[14:03]2017DOTA2亚洲邀请赛开幕式:12神兵演绎水墨中华
2017/04/01 DOTA
python mysqldb连接数据库
2009/03/16 Python
python去除所有html标签的方法
2015/05/05 Python
Python中用max()方法求最大值的介绍
2015/05/15 Python
简单讲解Python中的数字类型及基本的数学计算
2016/03/11 Python
Python编程判断这天是这一年第几天的方法示例
2017/04/18 Python
Python探索之自定义实现线程池
2017/10/27 Python
python逆向入门教程
2018/01/15 Python
scrapy爬虫完整实例
2018/01/25 Python
MUGLER官方网站:蒂埃里·穆勒香水
2019/11/26 全球购物
马来西亚排名第一的宠物用品店:Pets Wonderland
2020/04/16 全球购物
汽车维修专业毕业生的求职信分享
2013/12/04 职场文书
乡镇党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
如何使用 resize 实现图片切换预览功能
2021/08/23 HTML / CSS
python使用torch随机初始化参数
2022/03/22 Python
室外天线与收音机天线杆接合方法
2022/04/05 无线电