pythonpython-3.xargparse

Wildcard * not interpreted by python argparse on Windows


I'm trying to write a script that could take all files in a directory and allowing the user to use the * to refer to multiple files.

This is the line in which I set up the parser to receive the input files:

parser.add_argument('-f', '--files', help='The files to compare.', required=True, nargs='+')

This is the line of the error

Invalid argument: '.\\rmsd\\*.xyz'

This is the code I run to execute the script

python .\rsmd.py -r .\rmsd\1.xyz -f .\rmsd\*.xyz

My purpose is to let the user use the script in Windows and in Linux.


Solution

  • On Windows, python only receives the .\rmsd\*.xyz as string, it doesn't evaluate which files match the pattern. you can use e.g. the glob module to parse that.

    import glob
    my_txt_files = glob.glob("*.txt")  # returns list of filenames in current directory matching the pattern
    # e.g.:
    matched_files = glob.glob(arguments.files)
    

    Edit for platforms:

    You could check if more than one file was matched to make it more platform-independent

    import argparse
    import glob
    
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--files', nargs='+')
    arguments = parser.parse_args()
    matched_files = []
    for file in arguments.files:
        if glob.escape(file) != file:
            # -> There are glob pattern chars in the string
            matched_files.extend(glob.glob(file))
        else:
            matched_files.append(file)
    

    If you don't want to handle it in the program, you can start the program on Powershell with prior extension like this

    python rsmd.py -f (get-childitem *.txt)