使用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中ConfigParse模块的用法
Sep 29 Python
安装dbus-python的简要教程
May 05 Python
Python做简单的字符串匹配详解
Mar 21 Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
Mar 04 Python
用tensorflow搭建CNN的方法
Mar 05 Python
Python代码缩进和测试模块示例详解
May 07 Python
pandas去除重复列的实现方法
Jan 29 Python
Django高级编程之自定义Field实现多语言
Jul 02 Python
python实现淘宝购物系统
Oct 25 Python
浅析Python数字类型和字符串类型的内置方法
Dec 22 Python
pycharm安装及如何导入numpy
Apr 03 Python
Opencv常见图像格式Data Type及代码实例
Nov 02 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
全国中波电台频率表
2020/03/11 无线电
比较strtr, str_replace和preg_replace三个函数的效率
2013/06/26 PHP
yii2.0框架多模型操作示例【添加/修改/删除】
2020/04/13 PHP
讲两件事:1.this指针的用法小探. 2.ie的attachEvent和firefox的addEventListener在事件处理上的区别
2007/04/12 Javascript
javascript js cookie的存储,获取和删除
2007/12/29 Javascript
JavaScript判断密码强度(自写代码)
2013/09/06 Javascript
js 跳出页面的frameset框架示例介绍
2013/12/23 Javascript
jQuery.parseJSON(json)将JSON字符串转换成js对象
2014/07/27 Javascript
javascript格式化日期时间方法汇总
2015/06/19 Javascript
js实现表单多按钮提交action的处理方法
2015/10/24 Javascript
jQuery多条件筛选如何实现
2015/11/04 Javascript
如何使用headjs来管理和异步加载js
2016/11/29 Javascript
js实现Tab选项卡切换效果
2020/07/17 Javascript
JS使用cookie保存用户登录信息操作示例
2019/05/30 Javascript
Vue的transition-group与Virtual Dom Diff算法的使用
2019/12/09 Javascript
JavaScript组合设计模式--改进引入案例分析
2020/05/23 Javascript
分析并输出Python代码依赖的库的实现代码
2015/08/09 Python
Python中的super()方法使用简介
2015/08/14 Python
Python中生成Epoch的方法
2017/04/26 Python
pyside+pyqt实现鼠标右键菜单功能
2020/12/08 Python
使用Python实现将list中的每一项的首字母大写
2019/06/11 Python
Python基于Opencv来快速实现人脸识别过程详解(完整版)
2019/07/11 Python
python PyQt5/Pyside2 按钮右击菜单实例代码
2019/08/17 Python
Python 爬虫实现增加播客访问量的方法实现
2019/10/31 Python
Python列表切片常用操作实例解析
2020/03/10 Python
使用python matploblib库绘制准确率,损失率折线图
2020/06/16 Python
python实现粒子群算法
2020/10/15 Python
最新大学职业规划书范文
2013/12/30 职场文书
经费申请报告
2015/05/15 职场文书
党支部培养考察意见
2015/06/02 职场文书
八月一日观后感
2015/06/10 职场文书
工作收入证明范本
2015/06/12 职场文书
入党函调证明材料
2015/06/19 职场文书
高二英语教学反思
2016/03/03 职场文书
JavaWeb 入门:Hello Servlet
2021/07/16 Java/Android
SQL IDENTITY_INSERT作用案例详解
2021/08/23 MySQL