Last active
August 25, 2016 01:19
-
-
Save bravegnu/57cdff2a45afe3bc3e9f to your computer and use it in GitHub Desktop.
Implementation of head using docopt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Usage: head [options] [FILE]... | |
-c K, --bytes=K print the first K bytes of each file; | |
with the leading `-', print all but the last | |
K bytes of each file | |
-n K, --lines=K print the first K lines instead of the first 10; | |
with the leading `-', print all but the last | |
K lines of each file [default: 10] | |
-q, --quiet, --silent never print headers giving file names | |
-v, --verbose always print headers giving file names | |
--help display this help and exit | |
--version output version information and exit | |
""" | |
import sys | |
from collections import namedtuple | |
import docopt | |
HeadParams = namedtuple("HeadParams", "version bytes lines print_header files") | |
def err(msg): | |
sys.stdout.write("head: {0}\n".format(msg)) | |
sys.exit(1) | |
def get_params(args): | |
try: | |
bytes = int(args["--bytes"]) if args["--bytes"] else None | |
except ValueError: | |
err("invalid value for bytes") | |
try: | |
lines = int(args["--lines"]) if args["--lines"] else None | |
except ValueError: | |
err("invalid value for lines") | |
silent = args["--silent"] | |
verbose = args["--verbose"] | |
version = args["--version"] | |
files = args["FILE"] | |
if not files: | |
files.append("-") | |
print_header = True | |
if len(files) == 1: | |
print_header = False | |
if silent: | |
print_header = False | |
if verbose: | |
print_header = True | |
return HeadParams(version, bytes, lines, print_header, files) | |
def print_one_head(fp, params): | |
if params.print_header: | |
sys.stdout.write("==> {0} <==\n".format(fp.name)) | |
if params.bytes: | |
sys.stdout.write(fp.read()[:params.bytes]) | |
else: | |
sys.stdout.write("".join(fp.readlines()[:params.lines])) | |
def head(): | |
args = docopt.docopt(__doc__) | |
params = get_params(args) | |
if params.version: | |
print("head version: 1.0.0") | |
return | |
for filename in params.files: | |
try: | |
if filename == "-": | |
print_one_head(sys.stdin, params) | |
else: | |
with open(filename) as fp: | |
print_one_head(fp, params) | |
except IOError as e: | |
err("error opening {0}: {1}".format(filename, e)) | |
if __name__ == "__main__": | |
head() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment