getopt and options with multiple arguments
Tom Anderson
twic at urchin.earth.li
Tue Dec 20 19:20:55 EST 2005
On Mon, 19 Dec 2005, pinkfloydhomer at gmail.com wrote:
> I want to be able to do something like:
>
> myscript.py * -o outputfile
>
> and then have the shell expand the * as usual, perhaps to hundreds of
> filenames. But as far as I can see, getopt can only get one argument
> with each option. In the above case, there isn't even an option string
> before the *, but even if there was, I don't know how to get getopt to
> give me all the expanded filenames in an option.
I'm really surprised that getopt doesn't handle this properly by default
(so getopt.getopt mimics unices with crappy getopts - since when was that
a feature?), but as Steven pointed out, getopt.gnu_getopt will float your
boat.
I have an irrational superstitious fear of getopt, so this is what i use
(it returns a list of arguments, followed by a dict mapping flags to
values; it only handles long options, but uses a single dash for them, as
is, for some reason, the tradition in java, where i grew up):
def arguments(argv, expand=True):
argv = list(argv)
args = []
flags = {}
while (len(argv) > 0):
arg = argv.pop(0)
if (arg == "--"):
args.extend(argv)
break
elif (expand and arg.startswith("@")):
if (len(arg) > 1):
arg = arg[1:]
else:
arg = argv.pop(0)
argv[0:0] = list(stripped(file(arg)))
elif (arg.startswith("-") and (len(arg) > 1)):
arg = arg[1:]
if (":" in arg):
key, value = arg.split(":")
else:
key = arg
value = ""
flags[key] = value
else:
args.append(arg)
return args, flags
def stripped(f):
"""Return an iterator over the strings in the iterable f in which
strings are stripped of #-delimited comments and leading and
trailing whitespace, and blank strings are skipped.
"""
for line in f:
if ("#" in line): line = line[:line.index("#")]
line = line.strip()
if (line == ""): continue
yield line
raise StopIteration
As a bonus, you can say @foo or @ foo to mean "insert the lines contained
in file foo in the command line here", which is handy if, say, you have a
file containing a list of files to be processed, and you want to invoke a
script to process them, or if you want to put some standard flags in a
file and pull them in on the command line. Yes, you could use xargs for
this, but this is a bit easier. If you don't want this, delete the elif
block mentioning the @, and the stripped function. A slightly neater
implementation not involving list.pop also then becomes possible.
tom
--
Hit to death in the future head
More information about the Python-list
mailing list