linux系统more基本命令python源码分享

此贴python源码是linux系统more基本命令的实现。
实现linux中more的基本功能,当more后加一个文件名参数时候,分屏显示按空格换页,按回车换行',在左下角显示百分比;
以处理管道参数的输入,处理选项+num:从指定行开始显示,+/string :查找字符串,从指定字符串之后开始显示

运行环境:安装有PYTHON的linux系统

调用示例:
more.py [+num ] [+/pattern] filename
command|./more.py [+num ] [+/pattern]
more.p --help 输出帮助信息
num 是 要从第几行开始显示,pattern是要在文件中查找的字符串


#!/usr/bin/env python
# -*- coding:utf-8-*-
#文件名字:more.pyimport os
import sys
import curses      #用于获取终端的尺寸
import re              #用于字符匹配
import signal      #用于处理ctrl+c中断
import fcntl        # 处理显示过程中屏幕的变化
import termios  #获取终端信息
import struct
page_len = 0   #满屏时可以显示的最大行数
line_len = 0   #满屏时每行可以显示的最大字节数
sig_up = 0    #中断信号标志
winsz_chg = 0   #窗口大小改变标志def win_sz_chg(signum, frame):'''  函数功能:本函数是屏幕变化信号的处理函数'''global page_len, line_len, winsz_chgwinsz_chg = 1signal.signal(signal.SIGWINCH, signal.SIG_IGN)s = struct.pack("HHHH", 0, 0, 0, 0)  a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ , s))#获取当前窗口的大小page_len = int(a[0]) - 1  #留一行显示进度line_len = int(a[1])signal.signal(signal.SIGWINCH, win_sz_chg) #不调用会导致只能检测一次屏幕变化signal.signal(signal.SIGWINCH, win_sz_chg)  #接收处理窗口改变信号def term_do_exit(signum, frame):'''  函数功能:键盘中断信号的响应函数'''global sig_upsig_up = 1           #将键盘中断标志置1os.system("stty -F /dev/tty echo") #恢复终端输出回车有效状态os.system("stty -F /dev/tty -cbreak")#重新设着屏幕为输入字符回显状态returnsignal.signal(signal.SIGINT, term_do_exit)   #接收并处理键盘中断信号def usage():'''显示脚本的各参数的含义和调用格式'''print "-----------------usage-----------------"print "1./more.py [+num] [+/pattern] filename"print "2 command | ./more.py"print "num: Start at line number num. "print "pattern:Start at line number num."print "space: next page"print "q :do_exit the program"print "enter:next line"print"----------------------------------------"sys.exit()def do_exit():'''用于系统退出 '''os.system("stty -F /dev/tty echo") #恢复终端输出回车有效状态os.system("stty -F /dev/tty -cbreak")#重新设着屏幕为输入字符回显状态sys.exit()def is_input():''' 检测是否有管道数据输入 '''try:f = sys.stdin.fileno()  #判断时候有管道输入init_tty = termios.tcgetattr(f)     #当没有管道输入,也没有参数时候,显示提示return 0except:return 1def get_line_num(args):''' 从命令行参数中获取开始显示的指定行参数:args:从命令行获取的参数返回值:要开始显示的指定行  '''line_num = 1for i in args:            #匹配要从第几行开始的行数ln = re.search(r'\+\d+', str(i))if ln:line_num = int(ln.group().lstrip('+'))#采用正则表达式处理去掉‘+’,得到开始显示的行号breakreturn line_numdef get_patstr(args):'''从命令行中获取要查找的字符串参数:args:从命令行中获取的参数为返回值:要查找的字符串:  '''patstr = ""for i in args:            #获取要匹配的字符串pa = re.search(r'(\+\/\w*[^\s])', str(i))if pa:breakif pa:patstr = str(pa.group().lstrip('+/'))return patstrdef get_args():'''用于从命令行获取参数,解析各参数返回值:(line_num,patstr,fp):要开始显示的指定行,要查找的字符串,要操作的文件对象 '''line_num = 1patstr = ""args = sys.argv[1:]if not args:if is_input():      #在没有参数时候,判断是否为管道命令输入,不是提示正确输入参数fp = sys.stdinreturn (line_num, patstr, fp)else:usage()else:if args[-1] == "--help":usage()line_num = get_l
2000
ine_num(args)patstr = get_patstr(args)if '+' not in args[-1]:filename = args[-1]if not os.path.exists(filename):print " 没有那个文件或目录"do_exit()else:fp = open(filename)else:if not is_input():usage()else:fp = sys.stdinreturn (line_num, patstr, fp)def get_screen_size():''' 用于获取文件显示终端的尺寸   '''global page_len, line_len       screen = curses.initscr()       page_len, line_len = screen.getmaxyx()#获取屏幕显示尺寸page_len = page_len - 2   #去掉输入命令那行,和最后要显示more的那一行curses.endwin()     #此处不结束会导致后面显示的乱码def show_more(pre_pg_len):''' 等待键盘输入命令 ,进行相应的处理。:param pre_pg_len:屏幕改变以前保存的可显示的最大行数'''global  sig_up, winsz_chg, page_lenft = open('/dev/tty')   #打开标准终端输入sys.stdout.flush()    #刷新缓存输出,否则显示会出现问题c = ''while True:try:c = ft.read(1)#读取一个字符except IOError:if sig_up:do_exit()   #键盘中断退出程序if c == " ":print "\033[20D\033[K" #控制光标回到more--反白字体的行首,删除此行以达到more不随文字滚动效果if winsz_chg:        #如果此时屏幕大小变化,第一次返回之前屏幕满屏行数winsz_chg = 0return pre_pg_lenelse:return page_len     #当输入是空格时候,分屏显示,显示下一屏elif c == "q":print "\033[20D\033[K"return 0          #当输入是"q"时,退出显示elif c == '\n':print "\033[20D\033[K",return 1           #当输入是换行符时候,多显示一行def skip_ln(fp, line_num):''' 读取文件到指定开始显示的行  '''n = line_num - 1while n:fp.readline()if not fp:returnn = n - 1def search(fp, patstr):''' 在文件中寻找要查找的字符串。:param fp:要显示的文件对象    :param patstr:要查找的检索词  '''global  sig_uptext = ' 'while True:try:s = fp.read(1)         if not s:print "can not find the string in the file"do_exit()text = text + sif patstr in text:returnexcept IOError:if sig_up:do_exit()def show_prog(read_size, total_size):         '''  在显示屏幕的左下角显示反显的"More"当要显示的是一个文件时,同时显示已经显示文件的百分比当显示的是一个管道输入时,只显示“More”:param read_size: 已经显示的文件:param total_size:要显示的文件的总大小  '''if total_size:prog = int(read_size * 100 / float(total_size))print  "\033[7m --More--" + str(prog) + '%' + "\033[0m", #输出反白的文字“more”和显示百分数else:print  "\033[7m --More--" + "\033[0m", #输出反白的文字“more”returndef do_more(fp , line_num , patstr):'''分屏显示文件内容:param fp:要显示的文件对象:param page_len: 可显示的最大行数:param line_len:可每行可显示的最大字节数   '''global page_len, line_lenread_size = 0total_size = 0os.system("stty -F /dev/tty cbreak") #调用linux命令设置屏幕为不等回车os.system("stty -F /dev/tty -echo ")#设置屏幕为输入字符不回显if fp != sys.stdin:fp.seek(0, 2)  #获取文件的总字节数,以便后来显示输出的百分比 total_size = fp.tell()fp.seek(0, 0)if line_num != 1:skip_ln(fp, line_num)if patstr:search(fp, patstr)try:line = fp.readline(line_len)#按行读取文件,可以设置最大读取字数,当遇到“\n”时候,将"\n"读入结束。read_size = len(line)num_lns = 0while line:if num_lns == page_len: #每次输出满屏后,等待指令pre_pg_len = page_lenshow_prog(read_size, total_size)reply = show_more(pre_pg_len)           if reply == 0:breaknum_lns -= replyprint line.strip('\n') #用,来消除print 输出的换行符sys.stdout.flush()    #刷新缓存,否则会出现文件显示迟缓的问题read_size = read_size + len(line)num_lns += 1line = fp.readline(line_len)fp.close()except IOError:if sig_up:do_exit()if __name__ == '__main__':get_screen_size()  #获取显示终端的尺寸(line_num, patstr, fp) = get_args()do_more(fp, line_num, patstr)do_exit()

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

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

相关文章

crawlab爬虫python篇(保姆级图文教程)

文章目录 前言一、创建项目二、创建爬虫1.新建项目2.新建爬虫3. 上传文件总结资料解决方案记录前言 一个python刚到门槛水平的程序员是如何使用crawlab爬取网站,在这里做个图文教程记录下。 提示:这里做一个简单的网站爬取完整示例图文教程 一、创建项目 首先,我们将创建一…

Android平台GB28181设备接入模块之按需编码和双码流编码

技术背景 我们在做执法记录仪或指挥系统的时候,会遇到这样的情况,大多场景下,我们是不需要把设备端的数据,实时传给国标平台端的,默认只需要本地录像留底,如果指挥中心需要查看前端设备实时数据的时候&…

Python实现九宫格数独小游戏

1 问题 有1-9个数字,将他们填入一个3*3的九宫格中,使得他们的每行,每列,以及对角线上的和相等,且要求每个格子的数字不可以重复。使用python列出所有可能的组合。示例如下: 2 方法 每行,列,对角…

临时文档4

Redis有哪些数据类型 Redis主要有5种数据类型,包括String,List,Set,Zset,Hash,满足大部分的使用要求 Redis的应用场景 总结一 计数器 可以对 String 进行自增自减运算,从而实现计数器功能。…

uni-app优雅的实现时间戳转换日期格式

现在显示的格式如下图: 我期望统一格式,所以不妨前端处理一下,核心代码如下 filters: {// 时间戳处理formatDate: function(value, spe /) {value value * 1000let data new Date(value);let year data.getFullYear();let month data.…

API简意

API(Application Programming Interface)即应用程序接口,是一组定义的规则和协议,用于不同软件之间的交互和通信。它定义了软件组件之间如何相互访问和使用,简化了开发者的工作,提高了系统的可扩展性和灵活…

ubuntu上安装firefox geckodriver 实现爬虫

缘由:当时在windows 上运行chrom 的时候 发现要找到 浏览器和 webdirver 相匹配的 版本比较麻烦,当时搞了大半天才找到并安装好。 这次在ubuntu上尝试用firefox 实现爬虫 文章分为三个部分: 环境搭建浏览器弹窗输入用户名,密码的…

微信认证申请流程(个体工商户)

登录微信公众平台->设置->微信认证->开通 第一步:同意协议:签署《微信公众平台认证服务协议》 第二步:选择认证类型及填写认证资料 选择认证类型及上传申请公函 个体户资质信息 认证联系人信息:个体工商户联系人必须为法…

Python单例模式介绍、使用

一、单例模式介绍 概念:单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供访问该实例的全局访问点。 功能:单例模式的主要功能是确保在应用程序中只有一个实例存在。 优势: 节省系统资源:由…

【如何训练一个中译英翻译器】LSTM机器翻译模型部署之ncnn(python)(五)

系列文章 【如何训练一个中译英翻译器】LSTM机器翻译seq2seq字符编码(一) 【如何训练一个中译英翻译器】LSTM机器翻译模型训练与保存(二) 【如何训练一个中译英翻译器】LSTM机器翻译模型部署(三) 【如何训练…

【优选算法题练习】day8

文章目录 一、974. 和可被 K 整除的子数组1.题目简介2.解题思路3.代码4.运行结果 二、525. 连续数组1.题目简介2.解题思路3.代码4.运行结果 三、560. 和为 K 的子数组1.题目简介2.解题思路3.代码4.运行结果 总结 一、974. 和可被 K 整除的子数组 1.题目简介 974. 和可被 K 整…

React之组件的分类、使用,事件对象,this指向问题,修改状态以及受控组件与非受控组件

React之组件的介绍、创建与使用,事件对象,this指向问题,修改状态以及受控组件与非受控组件 一、组件基本介绍二、组件创建2.1 函数组件2.2 类组件 三、将组件提取到单独的js文件中四、有状态组件和无状态组件五、类组件的状态六、事件处理6.1 注册事件6.2 事件对象6.3 this指向…

【设计模式】单例设计模式详解(包含并发、JVM)

文章目录 1、背景2、单例模式3、代码实现1、第一种实现(饿汉式)为什么属性都是static的?2、第二种实现(懒汉式,线程不安全)3、第三种实现(懒汉式,线程安全)4、第四种实现…

day38-Mobile Tab Navigation(手机tab栏导航切换)

50 天学习 50 个项目 - HTMLCSS and JavaScript day38-Mobile Tab Navigation&#xff08;手机tab栏导航切换&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"…

3ds MAX 洗菜池

在家居中我们显然离不开这个对吧 首先绘制一个长方体作为基础 注意设置长宽高的网格大小&#xff0c;方便后续调整 俯视图网格线如下&#xff1a; 长方形变换为可编辑网络&#xff0c;并在【多边形】界面选择底面的所有多边形&#xff0c;按delete删除&#xff0c;形成一个壳体…

Github上方导航栏介绍

Code Watch&#xff1a;相当于关注&#xff0c;到时候这个项目又有什么操作&#xff0c;就会以通知的形式提醒你。 Fork&#xff1a;也就是把这个项目拉到你的仓库里&#xff0c;之后你可以对该代码进行修改&#xff0c;之后你可以发起Pull Request&#xff0c;简称PR&#xf…

vulnhub靶场之CengBox3

1.信息收集 输入命令&#xff1a;netdiscover -i eth0 -r 192.168.239.0 &#xff0c;发现181机器存活 输入命令nmap -p- -sV -O -Pn -A 192.168.239.181 &#xff0c;进行端口探测&#xff0c;发现存在22、80、443端口&#xff0c;还发现存在域名ceng-company.vm。 将域名c…

了解Unity编辑器之组件篇Tilemap(五)

Tilemap&#xff1a;用于创建和编辑2D网格地图的工具。Tilemap的主要作用是简化2D游戏中地图的创建、编辑和渲染过程。以下是一些Tilemap的主要用途&#xff1a; 2D地图绘制&#xff1a;Tilemap提供了一个可视化的编辑器界面&#xff0c;可以快速绘制2D地图&#xff0c;例如迷…

docker版jxTMS使用指南:新建用户并授权

本文讲解4.4版jxTMS中如何新建用户并授权&#xff0c;整个系列的文章请查看&#xff1a;[docker版jxTMS使用指南&#xff1a;docker版jxTMS使用指南&#xff1a;4.4版升级内容 docker版本的使用&#xff0c;请查看&#xff1a;docker版jxTMS使用指南 4.0版jxTMS的说明&#x…

python实现逻辑回归-清风数学建模-二分类水果数据

所用数据 &#x1f449;&#x1f449;&#x1f449;二分类水果数据 1.数据预处理 可以看到有4个特征&#xff0c;2种分类结果&#xff0c;最后4个没有分类结果的数据是拿来预测的 # 1. 数据预处理 import pandas as pd df pd.read_excel(oridata/二分类水果数据.xlsx,use…