I'm writing a small script, that should be able to handle multiple files. So I've added that files can be passed comma seperated, and do a arg.split(',') and then handle each one.
Now I've wanted to add asterisk as input possibility like
python myPythonScript.py -i folder/*
If I print the the argument to option -i right when I access it the first time I get
folder/firstFileInFolder.txt
But if I call my script with
python myPythonScript.py -i someFolder/someFile,folder/*
it works just fine. Does anyone have an idea, why python might behave that way?
Try to run this script
import sys
for arg in sys.argv:
print arg
python script.py *
your shell expands the asterisk before python sees it.
As mentioned in the comments, your shell is expanding the asterisk for the non-comma separated case. If you know that the user may specify an asterisk as part of a file name as in your second example, you can have Python do the path expansion by using the glob module.
from glob import glob
glob('*')
code which would allow either the shell or Python to do asterisk expansion may look something like this:
import glob
file_list = []
for pattern in sys.argv[1:]:
file_list.extend(glob.glob(pattern))
In your case, using a comma as a separator would then prevent you from using a comma as part of a filename.
Related
I have a situation where i need to take argument from command-line and use that string (expression) I need to print files based on that regex.
I want to use glob to parse my string as i can pass regex to filter.
excerpt from python file:
dated = sys.argv[1]
files = glob.glob(dated)
This throws me empty list
> python analysis.py <some_expression>
[]
However, if I give any value manually:
dated = '*.xlsx' # example sake
files = glob.glob(dated)
print(files)
it prints:
[<list of files conforming to the required filter>]
It's obvious that the CLI arguments that it prints above, but I want the CLI argument to work properly.
I tested manually if the arguments are actually testing and it worked, so the sys.argv[1] is working but the results are not getting parsed in the glob.glob()
any ideas if I am missing something somewhere?
The issue her is not in Python, but in the shell that invokes it. Most shells I know (definitely all Linux shells) perform glob expansion before passing arguments to the executable they spawn (your Python script, in this case). This means that, at most, sys.argv[1] would contain the first file matching the glob expression you pass, and anyway, applying glob on it would not do any good.
For example, if your work directory has files a.xlsx, b.xlsx and c.xlsx, and you invoke you code using:
python mycode.py *.xlsx
Then the shell will actually glob the argument you specified, and will pass the results to your script, making the following true:
sys.argv[1:] == [`a.xlsx`, `b.xlsx`, `c.xlsx`]
In fact, instead of explicitly invoking glob, you can simply iterate on sys.argv[1:].
I am trying to run a batch file through python; however, it is not recognizing the path. It stops reading the path after the space between 'Practice' and 'Folder'. How can I fix this? I've tried the r and using forward and backward slashes. Any help would be awesome. Thank you!
import os
Practice = r"C:\Users\Username\Desktop\Practice Folder\Practice.bat"
os.system(Practice)
'C:\Users\Username\Desktop\Practice' is not recognized as an internal
or external command, operable program or batch file.
Change working directory to the script directory as you are using some relative redirection paths. Pushd changes current directory to any drive and can map network drives. The && chains commands and only runs the right hand command if the left hand command succeeds. %UserProfile% is a standard environmental variable which is usually better then using a fixed path of C:\Users\Username.
import os
Practice = r'pushd "%UserProfile%\Desktop\Practice Folder" && Practice.bat'
os.system(Practice)
Try using call from subprocess module.
You need to enclose the command only in double quotes.
from subprocess import call
call(r'"C:\Users\Username\Desktop\Practice Folder\Practice.bat"')
(Notice the order of placing quotes...)
This would even work with os.system() provided you take care the order of quotation marks.
from os import system
system(r'"C:\Users\Username\Desktop\Practice Folder\Practice.bat"')
This should help fix your problem.
You probably need to use two types of quotation marks e.g.
import os
Practice = r"'C:\Users\Username\Desktop\Practice Folder\Practice.bat'"
os.system(Practice)
As it is, your string does not contain quotation marks - you need to include quotation marks within your string or else Windows will think that Folder\Practice.bat is an argument to the command rather than a continuation of the file path
Try this
import os
Practice = os.path.abspath(r"C:\Users\Username\Desktop\Practice Folder\Practice.bat")
Edit:
Something like this worked for me
os.system(r'"C:\Users\Username\Desktop\Practice Folder\Practice.bat"')
I want to pass data to a Python file using a pipe and also specifying an input file like:
cat file.txt|python script.py -u configuration.txt
I currently have this:
for line in fileinput.input(mode='rU'):
print(line)
I know there can be something with sys.argv but maybe using fileinput there is a clean way to do it?
Thanks.
From the documentation:
If a filename is '-', it is also replaced by sys.stdin. To specify an alternative list of filenames, pass it as the first argument to input().
So you can create a list containing '-' as well as the contents of sys.argv[1:] (the default), and pass that to input(). Or alternatively just put - in the list of arguments of your Python program:
cat file.txt|python script.py -u - configuration.txt
or
cat file.txt|python script.py -u configuration.txt -
depending on whether you want data provided on standard input to be processed before or after the contents of configuration.txt.
If you want to do anything more complicated than just processing the contents of standard input as if it were an input file, you probably should not be using the fileinput module.
I am trying to execute
"C:/Program Files/AnsysEM/AnsysEM15.0/Win64/Designer.exe" -runscriptandexit "C:/Python27/simula_SIR_Phyton.py"
that is a to run a script in a program and I am not able to do it. I have succeed to run a single file like:
os.startfile("C:/Users/amrodri.UPVNET/Desktop/Scripts/SIR_europea_script.adsn")
But I have not succeed with the other problem. Can anyone help?
I have tried among others:
os.system("C:/Program Files/AnsysEM/AnsysEM15.0/Win64/Designer.exe" -runscriptandexit "C:/Python27/simula_SIR_Phyton.py")
os.system takes a single string as an argument. In order to have double quotes within a Python string (without terminating the string), you need to escape them using a backslash, like this:
os.system("\"C:/Program Files/AnsysEM/AnsysEM15.0/Win64/Designer.exe\" -runscriptandexit \"C:/Python27/simula_SIR_Phyton.py\"")
Or, alternatively, use single quotes instead:
os.system("'C:/Program Files/AnsysEM/AnsysEM15.0/Win64/Designer.exe' -runscriptandexit 'C:/Python27/simula_SIR_Phyton.py'")
See:
os.system()
Using quotes at the command line (This is Unix-specific, but should also apply to Windows if you're using something like PowerShell)
the culprit here is the space between Program and files. In windows, when you want to execute an address with an space in it, you need to put it between "", which is going to get mixed with Python's quotations. An easy solution would be to use raw '' in Python. For example:
import os
ansysedt_exe = r'"C:\Program Files\AnsysEM\AnsysEM16.0\Win64\ansysedt.exe" -runscriptandexit C:\automation\test_1.py'
print ansysedt_exe
os.system(ansysedt_exe)
Please notice that the designer address was put between "c:\...\designer.exe" because of the space in program files folder name, but we don't have to do the same for the script address, because there is no space there. Also just a heads up, in R16, designer.exe is going to be merged with AnsysEDT.exe.
I am attempting to write a script that utilises sys.argv to wrap the scp command. The idea, is that you will be able to run: pyscp folder/* host but if I run this script with those arguments:
import sys
for arg in sys.argv:
print arg
I get a list of all the folders inside folder:
pyscp.py
folder/0
folder/1
folder/2
folder/3
folder/4
folder/5
folder/67
folder/8
folder/9
host
Assuming a UNIXoid operating system: The shell is expanding the * into the matching files. Try to call your script like
pyscp "folder/*" host
The quotes keep the shell from interpreting the * character.
If you do not escape the asterisk, the shell is performing filename expansion for you. The pattern including the asterisk becomes replaced with an alphabetically sorted list of file names matching the pattern before your Python program becomes executed. You can prevent the shell from performing filename expansion using e.g. single quotes, i.e.
pyscp 'folder/*' hostname
You can then do this yourself within Python using the glob module and control things the way you want it.
The shell is expanding the file list for you. You can leverage this by allowing multiple parameters in the command.
import sys
files = sys.argv[1:-1]
host = sys.argv[-1]
Now you have a more flexible program that lets caller jump through whatever hoops he wants for the transfer, like maybe all text files in folder1 plus anything that's changed in the last day in folder2 (on a linux machine):
pyscp folder1/*.txt `find -mtime -1` example.com