I've got a dozen programs that can accept input via stdin or an option, and I'd like to implement the same features in a similar way for the output.
The optparse code looks like this:
parser.add_option('-f', '--file',
default='-',
help='Specifies the input file. The default is stdin.')
parser.add_option('-o', '--output',
default='-',
help='Specifies the output file. The default is stdout.')
The rest of the applicable code looks like this:
if opts.filename == '-':
infile = sys.stdin
else:
infile = open(opts.filename, "r")
if opts.output == '-':
outfile = sys.stdout
else:
outfile = open(opts.output, "w")
This code works fine and I like its simplicity - but I haven't been able to find a reference to anyone using a default value of '-' for output to indicate stdout. Is this a good consistent solution or am I overlooking something better or more expected?
Discussion. &> or >& is a shortcut that simply sends both STDOUT and STDERR to the same place—exactly what we want to do.
Input/Output (I/O) redirection in Linux refers to the ability of the Linux operating system that allows us to change the standard input ( stdin ) and standard output ( stdout ) when executing a command on the terminal. By default, the standard input device is your keyboard and the standard output device is your screen.
Understanding the concept of redirections and file descriptors is very important when working on the command line. To redirect stderr and stdout , use the 2>&1 or &> constructs.
For input files you could use fileinput
module. It follows common convention for input files: if no files given or filename is '-' it reads stdin, otherwise it reads from files given at a command-line.
There is no need in -f
and --file
options. If your program always requires an input file then it is not an option.
-o
and --output
is used to specify the output file name in various programs.
#!/usr/bin/env python
import fileinput
import sys
from optparse import OptionParser
parser = OptionParser()
parser.add_option('-o', '--output',
help='Specifies the output file. The default is stdout.')
options, files = parser.parse_args()
if options.output and options.output != '-':
sys.stdout = open(options.output, 'w')
for line in fileinput.input(files):
process(line)
argparse
module allows you to specify explicitly files as arguments:
#!/usr/bin/env python
import fileinput
import sys
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('files', nargs='*', help='specify input files')
group = parser.add_mutually_exclusive_group()
group.add_argument('-o', '--output',
help='specify the output file. The default is stdout')
group.add_argument('-i', '--inplace', action='store_true',
help='modify files inplace')
args = parser.parse_args()
if args.output and args.output != '-':
sys.stdout = open(args.output, 'w')
for line in fileinput.input(args.files, inplace=args.inplace):
process(line)
Note: I've added --inplace
option in the second example:
$ python util-argparse.py --help
usage: util-argparse.py [-h] [-o OUTPUT | -i] [files [files ...]]
positional arguments:
files specify input files
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
specify the output file. The default is stdout
-i, --inplace modify files inplace
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With