A Template for Python Unix Utilities, Revisited

A long time ago, I posted a simple template for writing text-processing Unix utilities in Python. Since we're not in 2009 anymore, I figured it's time to port it to Python 3.

Differences between the old 2.5 compatible version is the use of argparse instead of optparse (which is still supported) and that the fileinput module now supports the with statement. I've also used the new string formatting syntax.

Here's the script:

#! /usr/bin/env python3
# A template for building unix style command line utilities like head(1),
# nl(1), or cat(1).
# Released as public domain, or licensed under either CC0 or the MIT/X11
# license, whichever gives you the most rights in your legislation.
import fileinput
import argparse

VERSION = '0.1.0'

# Set up the command line parser. The -h and --help switches are automatically
# enabled. See http://docs.python.org/library/argparse.html
ap = argparse.ArgumentParser(description='Utility for processing text.')

ap.add_argument('--version', action='version', version='%(prog)s ' + VERSION)
ap.add_argument('files', metavar='FILE', nargs='*',
                help='the files to read')
ap.add_argument('-l', '--list-filenames', action='store_true',
                help='List filenames')
ap.add_argument('-n', '--number', action='store_true',
                help='Print line numbers')

args = ap.parse_args()

# Iterate over all input files: If no file names are given on the command line,
# read from stdin. Otherwise iterate over all given files, with '-' being
# stdin. See http://docs.python.org/library/fileinput.html
with fileinput.input(args.files) as f:
    for line in f:
        if args.list_filenames and f.isfirstline():
            print('==>', f.filename(), '<==')

        if args.number:
            print('{}:{}: {}'.format(
                f.lineno(), f.filelineno(), line), end='')
            print(line, end='')


And here's the template again for download.