On Mon, 19 Dec 2005, [EMAIL PROTECTED] 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
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to