I am creating a terminal based python application whereby the user drags and drops a csv file into the terminal to get the file path. The file path is therefore escaped.
How do I remove all instances of this?
For example, I have a file
thisisatestfile/\(2).csv
but when I drag it into terminal it appears as:
thisisatestfile\:\\\(2\).csv
I have a list of all the shell escape characters that I need to remove:
link to characters
I am not very good at regex so any help much appreciated!
I just implemented this with shlex.split
>>> shlex.split('thisisatestfile/\(2).csv')
['thisisatestfile/(2).csv']
Since this method is intended for taking a raw shell invocation and returning a list of args to be passed to, e.g., subprocess.Popen, it returns a list. If you know you only have a single string to process, just grab the first element of the returned list.
>>> shlex.split('thisisatestfile/\(2).csv')[0]
'thisisatestfile/(2).csv'
Related
I have a text file with a path that goes like this:
r"\\user\data\t83\rf\Desktop\QA"
When I try to read this file a print a line it returns the following string, I'm unable to open the file from this location:
'r"\\\\user\\data\\t83\\rf\\Desktop\\QA"\n'
Seems you've got Python code in your text file, so either sanitize your file, so it only includes the actual path (not a Python string representation) or you can try to fiddle with string replace until you're satisfied, or just evaluate the Python string.
Note that using eval() opens Padora's box (it as unsafe as it gets), it's safer to use ast.literal_eval() instead.
import ast
file_content = 'r"\\\\user\\data\\t83\\rf\\Desktop\\QA"\n'
print(eval(file_content)) # do not use this, it's only shown for the sake of completeness
print(ast.literal_eval(file_content))
Output:
\\user\data\t83\rf\Desktop\QA
\\user\data\t83\rf\Desktop\QA
Personally, I'd prefer to sanitize the file, so it only contains \\user\data\t83\rf\Desktop\QA
\ will wait for another character to form one like \n (new line) or \t (tab) therefore a single backslash will merge with the next character. To solve this if the next character is \\ it will represent the single backslash.
my subprocess.call problem is that my shortcut target is with extra INI file which is LIV2.INI and my exe file should run whit it . and my target link in shortcut looks like this
"C:\Program Files (x86)\AMO\EXE\PROGRAM LIVE 2.exe" LIV2.INI
i tried this
subprocess.call('"C:\Users\admin\Desktop\PROGRAM LIVE 2.exe" LIV2.INI')
and i tried this
subprocess.call('C:\Users\admin\Desktop\PROGRAM LIVE 2.exe LIV2.INI')
and i still get error that the ini file missing ? How can i fix this :)
THank you in advance
ERROR : INI FILE Missing or Wrong Name
Please also edit your question to actually include the error since you will get a syntax error, not an error that the ini file is missing.
You have two issues here, first you have a syntax error since "\Us" is not a valid string in python. \u marks the start of a Unicode escape sequence and the character S is not a valid unicode escape key. You can fix this by using double \\ to escape the \ character and tell python you want your string to include a \ and not use it as the start of a escape sequence.
Secondly, subprocess.call excpects a list, not a string (unless you set shell=True; but don't do that, since it means you have to manually escape things which you have already discovered is hard). The first element of the list
is the executable to run and the rest are command line arguments. For example if you wanted to run pythoneand print "hello world" you would type:
subprocess.call(['python', '-c', 'print ("hello world")'])
Notice the missing quotes around the python string? You don't need those since the command line arguments are passed in raw and no shell will attempt to split them if you don't include quotes.
Putting it all together creates something like this:
subprocess.call(['C:\\Users\\admin\\Desktop\\PROGRAM LIVE 2.exe', 'LIV2.INI'])
Notice the double backslashes and how each command line argument is its own list element.
While writing a small Python script, I noticed that when the string "????" is passed as a command-line argument, it converts to "data" during program execution. Now, I am unsure whether this is a string or some other kind of data type. Finding information on this has been tricky, given the search terms.
Why does this happen and what does it mean?
? is a shell wildcard character, it matches any character (similar to . in a regular expression). So an unquoted ???? expands to all filenames with 4 characters. data is presumably the first such filename alphabetically in your directory.
See the output of
echo ????
If you want to pass ???? literally to the script, quote it.
python yourscript.py '????'
I'm using subprocess.call where you just give it an array of argumets and it will build the command line and execute it.
First of all is there any escaping involved? (for example if I pass as argument a path to a file that has spaces in it, /path/my file.txt will this be escaped? "/path/my file.txt")
And is there any way to get this command line that's generated (after escaping and all) before being executed?
As I need to check if the generated command line is not longer than certain amount of characters (to make sure it will not give an error when it gets executed).
If you're not using shell=True, there isn't really a "command line" involved. subprocess.Popen is just passing your argument list to the underlyingexecve() system call.
Similarly, there's no escaping, because there's no shell involved and hence nothing to interpret special characters and nothing that is going to attempt to tokenize your string.
There isn't a character limit to worry about because the arguments are never concatenated into a single command line. There may be limits on the maximum number of arguments and/or the length of individual arguments.
If you are using shell=True, you have to construct the command line yourself before passing it to subprocess.
I am quite new to python and i struck an issue wherein, I am dynamically retrieving a string from a dictionary which looks like this
files="eputilities/epbalancing_alb/referenced assemblies/model/cv6_xmltypemodel_xp2.cs"
I am unable to to perform any actions on this particular file as it is reading the path as 2 different strings
eputilities/epbalancing_alb/referenced and assemblies/model/cv6_xmltypemodel_xp2.cs
as there is a space between referenced and assemblies.
I wanted to know how to convert this to raw_string (ignore the space, but still keep the space between the two and consider it as one string)
I'm not able to figure this out although several comments where there on the web.
Please do help.
Thanks
From the comments to the other answer, I understand that you want to execute some external tool and pass a parameter (a filename) to it. This parameter, however, has spaces in it.
I'd propose to approaches; definitely, I'd use subprocess, not os.system.
import subprocess
# Option 1
subprocess.call([path_to_executable, parameter])
# Option 2
subprocess.call("%s \"%s\"" % (path_to_executable, parameter), shell=True)
For me, both worked, please check if they work yor you as well.
Explanations:
Option 1 takes a list of strings, where the first string has to be the path to the executable and all others are interpreted as command line arguments. As subprocess.call knows about each of these entities, it properly calls the external so that it understand thatparameter` is to be interpreted as one string with spaces - and not as two or more parameters.
Option 2 is different. With the keyword-argument shell=True we tell subprocess.call to execute the call through a shell, i.e., the first positional argument is "interpreted as if it was typed like this in a shell". But now, we have to prepare this string accordingly. So what would you do if you had to type a filename with spaces as a parameter? You'd put it between double quotes. This is what I do here.
Standard string building in python works like this
'%s foo %s'%(str_val_1, str_val_2)
So if I'm understanding you right either have a list of two strings or two different string variables.
For the prior do this:
' '.join(list)
For the latter do this:
'%s %s'%(string_1, string_2)