使用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使用append合并两个数组的方法
Apr 28 Python
python中安装Scrapy模块依赖包汇总
Jul 02 Python
基于python实现KNN分类算法
Apr 23 Python
详解python3安装pillow后报错没有pillow模块以及没有PIL模块问题解决
Apr 17 Python
Python对ElasticSearch获取数据及操作
Apr 24 Python
python实现基于朴素贝叶斯的垃圾分类算法
Jul 09 Python
django框架两个使用模板实例
Dec 11 Python
python实现最速下降法
Mar 24 Python
Pycharm生成可执行文件.exe的实现方法
Jun 02 Python
Python 私有属性和私有方法应用场景分析
Jun 19 Python
使用Python绘制台风轨迹图的示例代码
Sep 21 Python
Python爬虫基础讲解之请求
May 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
php银联网页支付实现方法
2015/03/04 PHP
帝国cms目录结构分享
2015/07/06 PHP
PHP实现实时生成并下载超大数据量的EXCEL文件详解
2017/10/23 PHP
Yii框架连表查询操作示例
2019/09/06 PHP
PHP getID3类的使用方法学习笔记【附getID3源码下载】
2019/10/18 PHP
AngularJS入门教程(二):AngularJS模板
2014/12/06 Javascript
jQuery中position()方法用法实例
2015/01/16 Javascript
轻松掌握JavaScript状态模式
2016/09/07 Javascript
js调用父框架函数与弹窗调用父页面函数的简单方法
2016/11/01 Javascript
开源免费天气预报接口API及全国所有地区代码(国家气象局提供)
2016/12/26 Javascript
flag和jq on 的绑定多个对象和方法(必看)
2017/02/27 Javascript
JS实现异步上传压缩图片
2017/04/22 Javascript
微信小程序下拉刷新界面的实现
2017/09/28 Javascript
vue+canvas实现炫酷时钟效果的倒计时插件(已发布到npm的vue2插件,开箱即用)
2018/11/05 Javascript
基于axios 的responseType类型的设置方法
2019/10/29 Javascript
react使用CSS实现react动画功能示例
2020/05/18 Javascript
[01:18:43]2014 DOTA2华西杯精英邀请赛5 24 iG VS DK
2014/05/25 DOTA
介绍Python中的一些高级编程技巧
2015/04/02 Python
在Python的Flask框架下使用sqlalchemy库的简单教程
2015/04/09 Python
Python中easy_install 和 pip 的安装及使用
2017/06/05 Python
python通过文本在一个图中画多条线的实例
2020/02/21 Python
python3通过qq邮箱发送邮件以及附件
2020/05/20 Python
django template实现定义临时变量,自定义赋值、自增实例
2020/07/12 Python
Python3.9.1中使用split()的处理方法(推荐)
2021/02/07 Python
HTML5新特性 多线程(Worker SharedWorker)
2017/04/24 HTML / CSS
video.js支持m3u8格式直播的实现示例
2020/05/20 HTML / CSS
美国求婚钻戒网站:Super Jeweler
2016/08/27 全球购物
意大利网上药房:Farmacia 33
2020/01/27 全球购物
如何处理简单的PHP错误
2015/10/14 面试题
大一学生职业生涯规划
2014/03/11 职场文书
人民调解员先进事迹材料
2014/05/08 职场文书
应届生自荐书
2014/06/23 职场文书
校园元旦活动总结
2014/07/09 职场文书
2014国庆节幼儿园亲子活动方案
2014/09/16 职场文书
英语导游词
2015/02/13 职场文书
python实现的web监控系统
2021/04/27 Python