您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“怎么用linux系統(tǒng)more基本命令的實現(xiàn)python源碼”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么用linux系統(tǒng)more基本命令的實現(xiàn)python源碼”吧!
實現(xiàn)linux中more的基本功能,當more后加一個文件名參數(shù)時候,分屏顯示按空格換頁,按回車換行',在左下角顯示百分比;
以處理管道參數(shù)的輸入,處理選項+num:從指定行開始顯示,+/string :查找字符串,從指定字符串之后開始顯示
運行環(huán)境:安裝有PYTHON的linux系統(tǒng)
調(diào)用示例:
more.py [+num ] [+/pattern] filename
command|./more.py [+num ] [+/pattern]
more.p --help 輸出幫助信息
num 是 要從第幾行開始顯示,pattern是要在文件中查找的字符串
`#!/usr/bin/env python` `# -*- coding:utf-8-*-` `#文件名字:more.py` `import` `os` `import` `sys` `import` `curses` `#用于獲取終端的尺寸` `import` `re` `#用于字符匹配` `import` `signal` `#用于處理ctrl+c中斷` `import` `fcntl` `# 處理顯示過程中屏幕的變化` `import` `termios` `#獲取終端信息` `import` `struct` `page_len` `=` `0` `#滿屏時可以顯示的最大行數(shù)` `line_len` `=` `0` `#滿屏時每行可以顯示的最大字節(jié)數(shù)` `sig_up` `=` `0` `#中斷信號標志` `winsz_chg` `=` `0` `#窗口大小改變標志` `def` `win_sz_chg(signum, frame):` `''' 函數(shù)功能:本函數(shù)是屏幕變化信號的處理函數(shù)'''` `global` `page_len, line_len, winsz_chg` `winsz_chg` `=` `1` `signal.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)` `#不調(diào)用會導致只能檢測一次屏幕變化` `signal.signal(signal.SIGWINCH, win_sz_chg)` `#接收處理窗口改變信號` `def` `term_do_exit(signum, frame):` `''' 函數(shù)功能:鍵盤中斷信號的響應(yīng)函數(shù)'''` `global` `sig_up` `sig_up` `=` `1` `#將鍵盤中斷標志置1` `os.system(``"stty -F /dev/tty echo"``)` `#恢復終端輸出回車有效狀態(tài)` `os.system(``"stty -F /dev/tty -cbreak"``)``#重新設(shè)著屏幕為輸入字符回顯狀態(tài)` `return` `signal.signal(signal.SIGINT, term_do_exit)` `#接收并處理鍵盤中斷信號` `def` `usage():` `'''顯示腳本的各參數(shù)的含義和調(diào)用格式'''` `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():` `'''用于系統(tǒng)退出 '''` `os.system(``"stty -F /dev/tty echo"``)` `#恢復終端輸出回車有效狀態(tài)` `os.system(``"stty -F /dev/tty -cbreak"``)``#重新設(shè)著屏幕為輸入字符回顯狀態(tài)` `sys.exit()` `def` `is_input():` `''' 檢測是否有管道數(shù)據(jù)輸入 '''` `try``:` `f` `=` `sys.stdin.fileno()` `#判斷時候有管道輸入` `init_tty` `=` `termios.tcgetattr(f)` `#當沒有管道輸入,也沒有參數(shù)時候,顯示提示` `return` `0` `except``:` `return` `1` `def` `get_line_num(args):` `''' 從命令行參數(shù)中獲取開始顯示的指定行` `參數(shù):args:從命令行獲取的參數(shù)返回值:要開始顯示的指定行 '''` `line_num` `=` `1` `for` `i` `in` `args:` `#匹配要從第幾行開始的行數(shù)` `ln` `=` `re.search(r``'\+\d+'``,` `str``(i))` `if` `ln:` `line_num` `=` `int``(ln.group().lstrip(``'+'``))``#采用正則表達式處理去掉‘+’,得到開始顯示的行號` `break` `return` `line_num` `def` `get_patstr(args):` `'''從命令行中獲取要查找的字符串` `參數(shù):args:從命令行中獲取的參數(shù)為返回值:要查找的字符串: '''` `patstr` `=` `""` `for` `i` `in` `args:` `#獲取要匹配的字符串` `pa` `=` `re.search(r``'(\+\/\w*[^\s])'``,` `str``(i))` `if` `pa:` `break` `if` `pa:` `patstr` `=` `str``(pa.group().lstrip(``'+/'``))` `return` `patstr` `def` `get_args():` `'''用于從命令行獲取參數(shù),解析各參數(shù)` `返回值:(line_num,patstr,fp):要開始顯示的指定行,要查找的字符串,要操作的文件對象 '''` `line_num` `=` `1` `patstr` `=` `""` `args` `=` `sys.argv[``1``:]` `if` `not` `args:` `if` `is_input():` `#在沒有參數(shù)時候,判斷是否為管道命令輸入,不是提示正確輸入?yún)?shù)` `fp` `=` `sys.stdin` `return` `(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.stdin` `return` `(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()` `#此處不結(jié)束會導致后面顯示的亂碼` `def` `show_more(pre_pg_len):` `''' 等待鍵盤輸入命令 ,進行相應(yīng)的處理。` `:param pre_pg_len:屏幕改變以前保存的可顯示的最大行數(shù)'''` `global` `sig_up, winsz_chg, page_len` `ft` `=` `open``(``'/dev/tty'``)` `#打開標準終端輸入` `sys.stdout.flush()` `#刷新緩存輸出,否則顯示會出現(xiàn)問題` `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:` `#如果此時屏幕大小變化,第一次返回之前屏幕滿屏行數(shù)` `winsz_chg` `=` `0` `return` `pre_pg_len` `else``:` `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` `-` `1` `while` `n:` `fp.readline()` `if` `not` `fp:` `return` `n` `=` `n` `-` `1` `def` `search(fp, patstr):` `''' 在文件中尋找要查找的字符串。` `:param fp:要顯示的文件對象 ` `:param patstr:要查找的檢索詞 '''` `global` `sig_up` `text` `=` `' '` `while` `True``:` `try``:` `s` `=` `fp.read(``1``) ` `if` `not` `s:` `print` `"can not find the string in the file"` `do_exit()` `text` `=` `text` `+` `s` `if` `patstr` `in` `text:` `return` `except` `IOError:` `if` `sig_up:` `do_exit()` `def` `show_prog(read_size, total_size): ` `''' 在顯示屏幕的左下角顯示反顯的"More"` `當要顯示的是一個文件時,同時顯示已經(jīng)顯示文件的百分比` `當顯示的是一個管道輸入時,只顯示“More”` `:param read_size: 已經(jīng)顯示的文件` `:param total_size:要顯示的文件的總大小 '''` `if` `total_size:` `prog` `=` `int``(read_size` `*` `100` `/` `float``(total_size))` `print` `"\033[7m --More--"` `+` `str``(prog)` `+` `'%'` `+` `"\033[0m"``,` `#輸出反白的文字“more”和顯示百分數(shù)` `else``:` `print` `"\033[7m --More--"` `+` `"\033[0m"``,` `#輸出反白的文字“more”` `return` `def` `do_more(fp , line_num , patstr):` `'''分屏顯示文件內(nèi)容` `:param fp:要顯示的文件對象` `:param page_len: 可顯示的最大行數(shù)` `:param line_len:可每行可顯示的最大字節(jié)數(shù) '''` `global` `page_len, line_len` `read_size` `=` `0` `total_size` `=` `0` `os.system(``"stty -F /dev/tty cbreak"``)` `#調(diào)用linux命令設(shè)置屏幕為不等回車` `os.system(``"stty -F /dev/tty -echo "``)``#設(shè)置屏幕為輸入字符不回顯` `if` `fp !``=` `sys.stdin:` `fp.seek(``0``,` `2``)` `#獲取文件的總字節(jié)數(shù),以便后來顯示輸出的百分比` `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)``#按行讀取文件,可以設(shè)置最大讀取字數(shù),當遇到“\n”時候,將"\n"讀入結(jié)束。` `read_size` `=` `len``(line)` `num_lns` `=` `0` `while` `line:` `if` `num_lns` `=``=` `page_len:` `#每次輸出滿屏后,等待指令` `pre_pg_len` `=` `page_len` `show_prog(read_size, total_size)` `reply` `=` `show_more(pre_pg_len) ` `if` `reply` `=``=` `0``:` `break` `num_lns` `-``=` `reply` `print` `line.strip(``'\n'``)` `#用,來消除print 輸出的換行符` `sys.stdout.flush()` `#刷新緩存,否則會出現(xiàn)文件顯示遲緩的問題` `read_size` `=` `read_size` `+` `len``(line)` `num_lns` `+``=` `1` `line` `=` `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()`
到此,相信大家對“怎么用linux系統(tǒng)more基本命令的實現(xiàn)python源碼”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。