您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么用linux系統more基本命令的實現python源碼”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么用linux系統more基本命令的實現python源碼”吧!
實現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.py` `import` `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_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)` `#不調用會導致只能檢測一次屏幕變化` `signal.signal(signal.SIGWINCH, win_sz_chg)` `#接收處理窗口改變信號` `def` `term_do_exit(signum, frame):` `''' 函數功能:鍵盤中斷信號的響應函數'''` `global` `sig_up` `sig_up` `=` `1` `#將鍵盤中斷標志置1` `os.system(``"stty -F /dev/tty echo"``)` `#恢復終端輸出回車有效狀態` `os.system(``"stty -F /dev/tty -cbreak"``)``#重新設著屏幕為輸入字符回顯狀態` `return` `signal.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` `0` `except``:` `return` `1` `def` `get_line_num(args):` `''' 從命令行參數中獲取開始顯示的指定行` `參數:args:從命令行獲取的參數返回值:要開始顯示的指定行 '''` `line_num` `=` `1` `for` `i` `in` `args:` `#匹配要從第幾行開始的行數` `ln` `=` `re.search(r``'\+\d+'``,` `str``(i))` `if` `ln:` `line_num` `=` `int``(ln.group().lstrip(``'+'``))``#采用正則表達式處理去掉‘+’,得到開始顯示的行號` `break` `return` `line_num` `def` `get_patstr(args):` `'''從命令行中獲取要查找的字符串` `參數:args:從命令行中獲取的參數為返回值:要查找的字符串: '''` `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():` `'''用于從命令行獲取參數,解析各參數` `返回值:(line_num,patstr,fp):要開始顯示的指定行,要查找的字符串,要操作的文件對象 '''` `line_num` `=` `1` `patstr` `=` `""` `args` `=` `sys.argv[``1``:]` `if` `not` `args:` `if` `is_input():` `#在沒有參數時候,判斷是否為管道命令輸入,不是提示正確輸入參數` `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()` `#此處不結束會導致后面顯示的亂碼` `def` `show_more(pre_pg_len):` `''' 等待鍵盤輸入命令 ,進行相應的處理。` `:param pre_pg_len:屏幕改變以前保存的可顯示的最大行數'''` `global` `sig_up, winsz_chg, page_len` `ft` `=` `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` `=` `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"` `當要顯示的是一個文件時,同時顯示已經顯示文件的百分比` `當顯示的是一個管道輸入時,只顯示“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”` `return` `def` `do_more(fp , line_num , patstr):` `'''分屏顯示文件內容` `:param fp:要顯示的文件對象` `:param page_len: 可顯示的最大行數` `:param line_len:可每行可顯示的最大字節數 '''` `global` `page_len, line_len` `read_size` `=` `0` `total_size` `=` `0` `os.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` `=` `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()` `#刷新緩存,否則會出現文件顯示遲緩的問題` `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系統more基本命令的實現python源碼”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。