12

I am running Python 3 on a Windows machine using PowerShell. I am trying to execute a Python file and then pass a number of files (file1.html, file2.html, etc.) as arguments using a wildcard character. I can get this to work, performing a couple of steps like below:

PS $files = Get-Item .\file*.html

PS python mypythonfile.py $files

My question is can this be done without having to use Get-Item and assigning the results to a variable? I tried running the same file like this python mypythonfile.py .\file*.html but this results in an error from the Python interpreter because PowerShell doesn't parse out the wildcard and passes the string with the wildcard.

Ajean
  • 5,528
  • 14
  • 46
  • 69
ddetts
  • 135
  • 1
  • 8
  • I don't think this actually has anything to do with Python. – Ajean May 10 '17 at 16:48
  • @Ajean - I probably shouldn't have added a Python tag, I'm new to this and only thought it might help with the context of the question. I agree, it's a PowerShell question, not Python. – ddetts May 10 '17 at 17:17
  • No problem, I went ahead and removed it - the rest of the question is perfectly fine (although me not being a Powershell person I can't answer it...). – Ajean May 10 '17 at 17:19

3 Answers3

24

It seems that you are in the interactive console. You do not need to assign the results of get-item to a variable, if that is all you are trying to achieve. Try this:

python mypythonfile.py (get-item .\file*.html)

Although this will work, you should really be passing Python the name of the file properly by using .FullName property of the resulting objects generated by get-item:

python mypythonfile.py (get-item .\file*.html).FullName
Adil Hindistan
  • 6,351
  • 4
  • 25
  • 28
9

While Windows shells (namely PowerShell and CMD) do support glob patterns, they don't expand the patterns themselves (unlike Unix shells). Instead commands that are supposed to support globbing must implement wildcard expansion themselves.

Python provides the glob module for that:

import sys
import glob

for arg in glob.glob(sys.args[1]):
    print(arg)

That allows your script to handle arguments with wildcards when called e.g. like this:

python script.py .\file*.html

Otherwise you need to use a PowerShell cmdlet that expands wildcard patterns for you and returns a list of paths, e.g. Get-ChildItem. Either collect the list in a variable:

$files = Get-ChildItem .\file*.html | Select-Object -Expand FullName
python script.py $files

or run the PowerShell statement in an expression:

python script.py (Get-ChildItem .\file*.html | Select-Object -Expand FullName)

Or you could have your Python script read from stdin:

import fileinput

for line in fileinput.input():
    print(line.replace('\n',''))

and pipe the file list into your script:

Get-ChildItem .\file*.html | Select-Object -Expand FullName | python script.py
Community
  • 1
  • 1
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
0

Do a $files | get-Member to see that Get-Item doesn't return a string but a System.IO.FileInfo object holding several entries.
If there are no spaces in the file names this could do:

 $files = (Get-Item .\file*.html) -join(' ')

Otherwise

$files =  '"'+((Get-Item .\file*.html) -join('" "'))+'"'