python中ls是什么_使用Python代码实现Linux中的ls遍历目录命令的实例代码

一、写在前面

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

20190906235445.png

在 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 命令的时候显示出来,例如:

20190906235446.png

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

> python test.py 1 3 5

Namespace(find_num=, integers=[1, 3, 5])

5

> python test.py 1 3 5 -min

Namespace(find_num=, 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,这里并没有输入路径,就会使用默认路径即当前目录,如下图:

20190906235447.png

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

20190906235448.png

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

20190906235449.png

到这里为止,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!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329907.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring中stereotype注解Component,Repository,Service,Controller

【README】 本文介绍了 spring4.0 下 org.springframework.stereotype 的注解类型,俗称刻板型注解(一成不变型); 包括 Component, Repository,Service, Controller ; 目录 【REA…

[中级]Java命令学习系列(五)——jhat

转载自 [中级]Java命令学习系列(五)——jhatjhat(Java Heap Analysis Tool),是一个用来分析java的堆情况的命令。之前的文章讲到过,使用jmap可以生成Java堆的Dump文件。生成dump文件之后就可以用jhat命令,将dump文件转成html的形式…

转:IDEA 创建类注释模板和方法注释模板

转自: IDEA 创建类注释模板和方法注释模板 - 简书  在使用Idea的时候,它的注释模板很简单,不够详细;所有大多数开发者都想设置一个比较详细的注释模板,我现在把我了解的创建类注释模板和方法注释模板的操作记录下来…

mappedbytebuffer_Java NIO Buffer【MappedByteBuffer】概述与FileChannel的联系

“ NIO【Non-blocking IO非阻塞式IO】,可以让你非阻塞的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似,主要…

[初级]Java命令学习系列(六)——jinfo

转载自 [初级]Java命令学习系列(六)——jinfojinfo可以输出java进程、core文件或远程debug服务器的配置信息。这些配置信息包括JAVA系统参数及命令行参数,如果进程运行在64位虚拟机上,需要指明-J-d64参数,如:jinfo -J-…

idea 调整代码格式

1. 格式化代码时, 不想格式化注释, refer2 IDEA格式化代码时,不想格式化注释怎么办?_缘自天方的博客-CSDN博客_idea不格式化注释很简单,只需要把 Enable JavaDoc formatting 去掉选中状态即可。附图如下:h…

python递归算法_python递归算法(上)

什么是递归 在函数内部,是可以调用其他函数的。如果一个函数在内部调用自身,就称这个函数就是递归函数。举个例子: 实现一个可以自定义重复打印你好的函数。 要实现重复打印,可能我们立马就会想到使用循环。如果要求不能使用循环呢…

[初级]Java命令学习系列(七)——javap

转载自 [初级]Java命令学习系列(七)——javapjavap是jdk自带的一个工具,可以对代码反编译,也可以查看java编译器生成的字节码。一般情况下,很少有人使用javap对class文件进行反编译,因为有很多成熟的反编译…

局域网物理机怎么访问虚拟机

前言 友链: 原文地址 ❓-背景- 现有物理机A,B。A中安装了虚拟机VM上面部署了服务(这里以mysql为例)。B需要访问A虚拟机中部署的服务。 -环境- 物理机A(192.168.135.161)物理机B(192.168.135.162&#xf…

springmvc新建拦截器

【1】web.xml中配置springmvc的配置文件路径 <!-- 配置 DispatcherServlet --><servlet><servlet-name>springDispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!…

householder变换qr分解matlab_【基础教程】Matlab实现傅里叶变换

傅立叶变换傅立叶变换是一种常见的分析方法&#xff0c;傅立叶变换将满足一定条件的函数表示为一些函数的加权和(或者积分)。可以分为四个类别&#xff1a; 1. 非周期连续性信号 对应于傅里叶变换&#xff0c;频域连续非周期 2. 周期性连续性信号 对应于傅立叶级数&#xff0c;…

Java开发必会的Linux命令

转载自 Java开发必会的Linux命令 必会Linux命令清单查找文件 find / -name filename.txt 根据名称查找/目录下的filename.txt文件。 find . -name "*.xml" 递归查找所有的xml文件 find . -name "*" |xargs grep "hello" 递归查找所有文件内容中包…

http连接池

转自 &#xff1a; 最近学习了Http连接池 - 五月的仓颉 - 博客园 【1】使用线程池与否的程序性能 我的任务定义&#xff1a;从0 累加到 100w&#xff1b; public class ThreadPoolMain {/*** 线程池测试*/private static final AtomicInteger THREAD_EXECUTED_TOTAL new At…

Quartz定时任务的基本搭建

前言 个人地址&#xff1a;Quartz定时任务的基本搭建 Quartz是一个完全由Java编写的开源作业调度框架&#xff0c;为在java应用程序中进行作业调度提供了简单又强大的机制。 Quartz中分为几个核心概念&#xff1a; Job - 表示一个工作&#xff08;任务&#xff09;&#xff0…

matlab 定义一个有自变量的方程_常微分方程:(第四章) 高阶微分方程

参考《常微分方程》第三版&#xff08;王高雄&#xff09;常微分方程王高雄 第四章 高阶微分方程_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com对于高阶微分方程&#xff0c;线性部分见4、5章&#xff0c;非线性部分见6章。4.1 线性微分方程的一般理论定义&#xff…

HttpClient api-连接池

【README】 本文 refer2 HttpClient Tutorialhttps://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/pdf/httpclient-tutorial.pdf 【2.3】http连接管理器 【2.3.1】可管理的连接与连接管理器 1&#xff09;http连接简述 HTTP 连接是复杂的、有状态的、线程…

使用SpringBoot搭建一个简单的webSocket服务

前言 个人地址&#xff1a;使用SpringBoot搭建一个简单的webSocket服务 什么是WebSocket&#xff1f; WebSocket是一个HTML5新增的协议,它的目的在浏览器和服务器之间建立一个不受限的双向实时通信的通道。比如&#xff0c;服务器可以任意时刻发送消息给浏览器。它是基于TCP&am…

cas 登录之后不跳转_图解JWT如何用于单点登录

点击上方“Java知音”&#xff0c;选择“置顶公众号”技术文章第一时间送达&#xff01;作者&#xff1a;流云诸葛http://cnblogs.com/lyzg/p/6132801.html推荐阅读(点击即可跳转阅读)1. 淘宝服务端高并发分布式架构演进之路2. IntelliJ IDEA 从入门到上瘾教程&#xff0c;2019…

转:java网络编程-HTTP编程

转自&#xff1a; java网络编程-HTTP编程_Stillsings的博客-CSDN博客HTTP编程Java HTTP编程支持模拟成浏览器的方式去访问网页URL, Uniform Resource Locator&#xff0c;代表一个资源URLConnection获取资源连接器根据URL的openConnection&#xff08;&#xff09;方法获得URL…

Centos7-通过RPM方式安装MySQL5.7

前言 Hallo&#xff0c;我们都知道开发时数据库是不可或缺的&#xff0c;本文就简单记录一下安装MySQL数据库的其中一种方式吧。 系统环境 系统&#xff1a;CentOS Linux 7.5 数据库版本&#xff1a;5.7 安装步骤 1. 从官网获取安装包 官方下载地址&#xff1a;https://ww…