实现目标

  1. $ myprog.py 打印帮助
  2. $ myprog.py -h/--help 打印帮助
  3. $ myprog.py input.txt 读取输入文件,输出到标准输出
  4. $ myprog.py input.txt -o output.txt 读取输入文件,输出到文件
  5. $ cat input.txt | myprog.py 读取标准输入,输出到标准输出
  6. $ cat input.txt | myprog.py 读取标准输入,输出到文件
  7. $ cat input.txt | myprog.py | less -N 接管道符

问题关键

没有指定输入文件时,需要判断 sys.stdin 是否为空,为空时打印帮助,不为空时从stdin读取
通过 sys.stdin.isatty() 方法即可判断,True表示 sys.stdin 为空

另外 signal.signal(signal.SIGPIPE, signal.SIG_DFL) 可避免接管道符退出时出现 IOError: [Errno 32] Broken pipe

示例代码

  1. #!/usr/bin/env python2
  2. # encoding: utf-8
  3. '''\033[1;3;32m
  4. normalizing file with multiple encodings to utf8
  5. \033[0m'''
  6. import sys
  7. import signal
  8. import textwrap
  9. import chardet
  10. reload(sys)
  11. sys.setdefaultencoding('utf8')
  12. signal.signal(signal.SIGPIPE, signal.SIG_DFL)
  13. __author__ = 'suqingdong'
  14. __version__ = '1.0'
  15. def main(infile=None, outfile=None):
  16. infile = sys.stdin if infile in ('-', 'stdin') else open(infile)
  17. outfile = sys.stdout if outfile in ('-', 'stdout') else open(outfile, 'w')
  18. with infile as inf, outfile as out:
  19. for line in inf:
  20. enc = chardet.detect(line)['encoding'] or 'gbk'
  21. line = line.decode(enc)
  22. out.write(line)
  23. if __name__ == '__main__':
  24. import argparse
  25. epilog = textwrap.dedent('''
  26. \033[36mexample:
  27. %(prog)s input.txt
  28. %(prog)s input.txt -o output.txt
  29. cat input.txt | %(prog)s
  30. cat input.txt | %(prog)s -o output.txt
  31. \033[33mcontact: {__author__}@novogene.com
  32. ''').format(**globals())
  33. parser = argparse.ArgumentParser(
  34. prog='norm_encoding',
  35. description=__doc__,
  36. epilog=epilog,
  37. formatter_class=argparse.RawTextHelpFormatter)
  38. parser.add_argument(
  39. 'infile',
  40. nargs='?',
  41. default='stdin',
  42. help='the input file which maybe contains multiple encodings [default: %(default)s]')
  43. parser.add_argument(
  44. '-o',
  45. '--outfile',
  46. default='stdout',
  47. help='the output file [default: %(default)s]')
  48. # 没有输入文件,其标准输入为空时,只打印帮助
  49. if (len(sys.argv) == 1) and sys.stdin.isatty():
  50. parser.print_help()
  51. exit()
  52. args = vars(parser.parse_args())
  53. main(**args)