Passing arguments with wildcards to a Python script

Question:

I want to do something like this:

c:data> python myscript.py *.csv

and pass all of the .csv files in the directory to my python script (such that sys.argv contains ["file1.csv", "file2.csv"], etc.)

But sys.argv just receives ["*.csv"] indicating that the wildcard was not expanded, so this doesn’t work.

I feel like there is a simple way to do this, but can’t find it on Google. Any ideas?

Asked By: Kiv

||

Answers:

You can use the glob module, that way you won’t depend on the behavior of a particular shell (well, you still depend on the shell not expanding the arguments, but at least you can get this to happen in Unix by escaping the wildcards 🙂 ).

from glob import glob
filelist = glob('*.csv') #You can pass the sys.argv argument
Answered By: Vinko Vrsalovic

In Unix, the shell expands wildcards, so programs get the expanded list of filenames. Windows doesn’t do this: the shell passes the wildcards directly to the program, which has to expand them itself.

Vinko is right: the glob module does the job:

import glob, sys

for arg in glob.glob(sys.argv[1]):
    print "Arg:", arg
Answered By: Ned Batchelder

If your script is a utility, I suggest you to define a function like this in your .bashrc to call it in a directory:

myscript() {
   python /path/myscript.py "$@"
}

Then the whole list is passed to your python and you can process them like:

for _file in sys.argv[1:]:
    # do something on file
Answered By: Ahmad

If you have multiple wildcard items passed in (for eg: python myscript.py *.csv *.txt) then, glob(sys.argv[1] may not cut it. You may need something like below.

import sys
from glob import glob

args = [f for l in sys.argv[1:] for f in glob(l)]

This will work even if some arguments dont have wildcard characters in them. (python abc.txt *.csv anotherfile.dat)

Answered By: najeem