Skip to content

Instantly share code, notes, and snippets.

@bpeterso2000
Last active August 29, 2015 14:00
Show Gist options
  • Save bpeterso2000/026dfa60701521b2f5ec to your computer and use it in GitHub Desktop.
Save bpeterso2000/026dfa60701521b2f5ec to your computer and use it in GitHub Desktop.
Emulating cat to demo creating Unix command look & feel with argparse
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
argparse Unix command demo
--------------------------
Simple demonstration of using argparse to emulated a Unix command's look & feel
Demonstrates stdin.
Emulates Unix 'cat' <GNU textutils> written by Torborjn Ganlund and
Richard M. Stallman. Note: Emulating the command is not all that useful
except that it provides something to compare against when demonstrating
argparse basics.
"""
__version__ = '0.1'
__author__ = '<author name(s)>'
__copyright__ = 'Copyright (c) <year> <person/organization>'
__license__ = '''
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.'''
import argparse
import fileinput
import sys
from glob import glob
from itertools import chain
def readlines(filenames, number):
if filenames:
filenames = chain.from_iterable(glob(i) for i in filenames)
for line in fileinput.input(filenames):
yield line
def squeeze_blanks(lines):
for line in lines:
if line.strip():
yield line
def number_nonblanks(lines):
linenum = 0
for line in lines:
if line.strip():
linenum += 1
yield '{} {}'.format(linenum, line)
else:
yield line
def number(lines):
for line in lines:
yield '{} {}'.format(fileinput.lineno(), line)
def show_ends(lines):
for line in lines:
yield line + '$'
def get_char(ord_):
if ord_ >= 0o40 and ord_ < 0o177:
# printable character
result = chr(ord_)
elif ord_ > 0o177:
# meta-character
result = 'M-' + chr(ord_ + 0o200)
else:
# control character
result = '^' + chr(ord_ + 0o100)
return result
def show_nonprinting(lines):
for line in lines:
yield ''.join([get_char(oct(ord(i))) for i in line])
def main(args):
lines = readlines(args.filenames, args.number)
if args.squeeze_blank:
lines = (i for i in lines if i.strip())
if args.number_nonblank and not (args.squeeze_blank and args.number):
lines = number_nonblanks(lines)
elif args.number:
lines = ('{} {}'.format(fileinput.lineno(), i) for i in lines)
if args.show_ends:
lines = (i + '$' for i in lines)
if args.show_tabs:
lines = (i.replace('\t', '^I') for i in lines)
if args.show_nonprinting:
lines = show_nonprinting(lines)
for line in lines:
sys.stdout.write(line)
if __name__ == '__main__':
# epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter)
description = 'Concatenate FILE(s), or standard input, to standard output.'
epilog = ('With no FILE, or when FILE is -, read standard input.\n\n'
'Report bugs to <bpeterso2000@yahoo.com>')
formatter = argparse.RawDescriptionHelpFormatter
parser = argparse.ArgumentParser(description=description, epilog=epilog,
formatter_class=formatter)
version = ("%(prog)s {version}\n{author}\n\n{copyright}\n{license}")
version = version.format(version=__version__, author=__author__,
copyright=__copyright__, license=license)
parser.add_argument('--version', action='version', version=version,
help='display this help and exit')
parser.add_argument('-A', '--show-all', action='store_true',
dest='show_all', help='equivalent to -vET')
parser.add_argument('-b', '--number-nonblank', action='store_true',
dest='number_nonblank',
help='number nonblank output lines')
parser.add_argument('-e', action='store_true',
help='equivalent to -vE')
parser.add_argument('-E', '--show-ends', action='store_true',
dest='show_ends', help='display $ at end of each line')
parser.add_argument('-n', '--number', action='store_true',
help='number all output lines')
parser.add_argument('-s', '--squeeze-blank', action='store_true',
dest='squeeze_blank',
help='never more than one single blank line')
parser.add_argument('-t', action='store_true',
help='equivalent to -vT')
parser.add_argument('-T', '--show-tabs', action='store_true',
dest='show_tabs', help='display TAB characters as ^I')
parser.add_argument('-u', action=None, help='(ignored)')
parser.add_argument('-v', '--show-nonprinting', action='store_true',
dest='show_nonprinting',
help='use ^ and M- notation, except for LFD and TAB')
parser.add_argument('filenames', nargs='*')
args = parser.parse_args()
print(args)
for option, flags in {'show-all': 'vET', 'e': 'vE', 't': 'vT'}.items():
if option in vars(args):
for flag in flags:
setattr(args, flag, True)
main(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment