逐步实现python版wc命令
Python 如何处理管道输入输出
sys.stdin 等于打开了一个文件对象,所有输入的文件都会写入到标准输入文件中(键盘)
sys.stdout 等于打来了一个文件对象,使用.write()把信息写入到标准输出文件中(屏幕)
判断行数:
1 #!/usr/bin/env python 2 #_*_ coding:UTF-8 _*_ 3 4 import sys 5 6 #遍历文件对象,并统计行数 7 def lineCount(f): 8 n = 0 9 for i in f: 10 n += 1 11 return n 12 13 input = sys.stdin 14 print(lineCount(input)) 15
文件对象的方法:
fd.read() 一次读取所有行,返回字符串
fd.readline() 一次读取一行,返回一个字符串
fd.readlines() 一次读取所有行,返回一个列表,每一行为一个元素
f.write() 写入文件
f.close() 关闭文件(每次打开文件,最好都要手动关闭文件)
利用while循环遍历文件
1 while True: 2 ....: data = fd.readline() 3 ....: if not data: 4 ....: break 5 ....: print(data)
文件输出:
sys.stdout.write() 文件写入到标准输出文件中去
print和stdout的区别:
1、print通常是调用一个stdout对象的write方法
2、print会先进行格式转换
3、print会在最后加上换行符
stdout的buffer
通过stdout输出的信息一般会先放在stdout的buffer中,然后等待输出完毕后,一次性输出
这里可以通过两种方式禁止写入buffer
1、sys.stdout.flush(),每次写入buffer,然后强制刷新到文件中
2、python -u scripts.py 执行python解释器的时候,指明不使用buffer,python 2.x 适用
例子:
1 import sys 2 import time 3 4 for i in range(10): 5 sys.stdout.write('>') #当然这里加上\n就会一个一个输出,因为sys.stdout是正行正行输出(加\n,就类似于print了) 6 sys.stdout.flush() #强制i刷新到stdout中去 7 time.sleep(1)
计算字符:
获取字符数 len(data)
获取单词数 len(data.split()) #以空格分隔,计算有几段
获取行数 data.count('\n') #统计\n出现的次数即可
1 #!/usr/bin/env python 2 import sys 3 data = sys.stdin.read() 4 chars = len(data) 5 words = len(data.split()) 6 lines = data.count('\n') 7 print('%s %s %s ' % (lines,words,chars)) #传统的字符串替换 8 print('%(lines)s %(words)s %(chars)s' % locals()) #高级用法,%(key)s,表示格式化关键字替换,后面就需要以字典的方式传入对应的key值,而locals(),表示当前环境下所有的变量和值的字典,所以这里可以进行替换 9 print('%(lines)s %(words)s %(chars)s' % {'lines':lines,'words':words,'chars':chars}) 这种方法和上面利用locals的方式是一样的,只不过locals的变量更多而已
没有命令和参数版本的wc:
1 #!/usr/bin/env python 2 import sys,os 3 4 if len(sys.argv) == 1: 5 data = sys.stdin.read() 6 else: 7 try: 8 filename = sys.argv[1] 9 except IndexError as e: 10 sys.exit('The %s need one parameter' % __file__) 11 12 if os.path.exists(filename): 13 try: 14 fd = open(filename) 15 data = fd.read() 16 fd.close() 17 except IOError as e: 18 sys.exit('The Parameter is a file,not a Directory') 19 else: 20 sys.exit('The %s is not exist' % filename) 21 22 chars = len(data) 23 words = len(data.split()) 24 lines = data.count('\n') 25 26 print('%(lines)s %(words)s %(chars)s' % locals())
Python的命令行参数
利用optparse模块,来添加参数和选项
1 #!/usr/bin/env python 2 # Author:Lee Sir 3 4 import sys 5 from optparse import OptionParser #导入optparser模块中的OptionParser类 6 7 parser = OptionParser() #实例化一个OptionParser类的对象parser,这里括号里可以添加一些提示信息,用户在执行help时输出(%prog表示脚本名称。例子:%prog [ -c| -l | -d] [file1]) 8 parser.add_option('-c','--char',dest='chars',action='store_true',default=False,help='only user to count chars') 9 10 #add_option 表示添加一个选项,-c为选项名称,--char为对应的长选项(可选),dest 表示在程序内引用该变量时的名称,action表示参数后面是否有值(有的话store,没有的话store_true/store_false),default表示该参数默认是添加还是不添加,help(执行-help会显示的内容) 11 parser.add_option('-w','--word',dest='words',action='store_true',default=False,help='only user to count words') 12 parser.add_option('-l','--line',dest='lines',action='store_true',default=False,help='only user to count lines') 13 14 #parse_args() 会返回一个元组,第一个元素为对象,存储着参数的使用情况,第二个为列表,存储着参数对应的值。(注意,第一个元素为对象,呈现形式很像字典,但不能用字典的方式读取,只能使用option.dest来读写) 15 options,args = parser.parse_args() 16 17 #默认参数,当同时没有-c,-l,-w时,设置这三个参数都是True 18 if not (options.chars or options.words or options.lines): 19 options.chars,options.words,options.lines = True,True,True 20 21 data = sys.stdin.read() 22 chars = len(data) 23 words = len(data.split()) 24 lines = data.count('\n') 25 26 if options.chars: #脚本后添加了-c,则option.chars = True 27 print(chars,end='\t') 28 if options.words: 29 print(words,end='\t') 30 if options.lines: 31 print(lines) 32
添加判断完善脚本:
os.Path对文件路径的处理
os.path.isdir 判断是否是目录
os.path.isfile 判断是否是文件
1 #!/usr/bin/env python 2 3 import os,sys 4 from optparse import OptionParser 5 def opt(): 6 'Get Command line parser' 7 parser = OptionParser() 8 parser.add_option('-c','--char',dest='chars',action='store_true',default=False,help='used to count chars') 9 parser.add_option('-w','--word',dest='words',action='store_true',default=False,help='used to count words') 10 parser.add_option('-l','--line',dest='lines',action='store_true',default=False,help='used to count lines') 11 option,args = parser.parse_args() 12 return option,args 13 14 def get_count(data): 15 'count for lines ,words or chars' 16 chars = len(data) 17 words = len(data.split()) 18 lines = data.count('\n') 19 return lines,words,chars 20 21 def print_wc(option,lines,words,chars,filename): 22 'print lines,words or chars' 23 if option.lines: 24 print lines, 25 if option.words: 26 print words, 27 if option.chars: 28 print chars, 29 print filename 30 31 def main(): 32 'main functions' 33 option,args = opt() 34 if not (option.chars or option.words or option.lines): 35 option.chars , option.words, option.lines = True,True,True 36 if args: 37 total_lines,total_words,total_chars = 0, 0, 0 38 for filename in args: 39 if os.path.isfile(filename): 40 with open(filename) as fd: 41 data = fd.read() 42 lines,words,chars = get_count(data) 43 print_wc(option,lines,words,chars,filename) 44 total_lines += lines 45 total_words += words 46 total_chars += chars 47 elif os.path.isdir(filename): 48 print >> sys.stderr,'%s is a directory' % filename #利用print写入到文件中去,注意这里仅仅适用于Python 2.x,python3是不支持的(可以用print(i,file=sys.stdout) 或者sys.stdout.write()) 49 else: 50 sys.exit('%s : No such file or Directory' % filename) 51 if len(args) > 1: 52 print_wc(option,total_lines,total_words,total_chars,'total') 53 else: 54 data = sys.stdin.read() 55 filename = '' 56 lines,words,chars = get_count(data) 57 print_wc(option,lines,words,chars,filename) 58 59 60 if __name__ == '__main__': 61 main()
逐步实现Python版本的wc命令
添加-n参数,来禁止显示total
1 #!/usr/bin/env python 2 3 import os,sys 4 from optparse import OptionParser 5 def opt(): 6 'Get Command line parser' 7 parser = OptionParser() 8 parser.add_option('-c','--char',dest='chars',action='store_true',default=False,help='used to count chars') 9 parser.add_option('-w','--word',dest='words',action='store_true',default=False,help='used to count words') 10 parser.add_option('-l','--line',dest='lines',action='store_true',default=False,help='used to count lines') 11 parser.add_option('-n',"--no-total",dest="nototal",action='store_true',default=False,help='not print total') 12 option,args = parser.parse_args() 13 return option,args 14 15 def get_count(data): 16 'count for lines ,words or chars' 17 chars = len(data) 18 words = len(data.split()) 19 lines = data.count('\n') 20 return lines,words,chars 21 22 def print_wc(option,lines,words,chars,filename): 23 'print lines,words or chars' 24 if option.lines: 25 print lines, 26 if option.words: 27 print words, 28 if option.chars: 29 print chars, 30 print filename 31 32 def main(): 33 'main functions' 34 option,args = opt() 35 if not (option.chars or option.words or option.lines): 36 option.chars , option.words, option.lines = True,True,True 37 if args: 38 total_lines,total_words,total_chars = 0, 0, 0 39 for filename in args: 40 if os.path.isfile(filename): 41 with open(filename) as fd: 42 data = fd.read() 43 lines,words,chars = get_count(data) 44 print_wc(option,lines,words,chars,filename) 45 total_lines += lines 46 total_words += words 47 total_chars += chars 48 elif os.path.isdir(filename): 49 print >> sys.stderr,'%s is a directory' % filename 50 else: 51 sys.exit('%s : No such file or Directory' % filename) 52 if len(args) > 1: 53 if not option.nototal:
56 print_wc(option,total_lines,total_words,total_chars,'total') 57 else: 58 data = sys.stdin.read() 59 filename = '' 60 lines,words,chars = get_count(data) 61 print_wc(option,lines,words,chars,filename) 62 63 64 if __name__ == '__main__': 65 main()
所有巧合的是要么是上天注定要么是一个人偷偷的在努力。