逐步实现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()