Concatenate path and filename - python

I have to build the full path together in python. I tried this:
filename= "myfile.odt"
subprocess.call(['C:\Program Files (x86)\LibreOffice 5\program\soffice.exe',
'--headless',
'--convert-to',
'pdf', '--outdir',
r'C:\Users\A\Desktop\Repo\',
r'C:\Users\A\Desktop\Repo\'+filename])
But I get this error
SyntaxError: EOL while scanning string literal.

Try:
import os
os.path.join('C:\Users\A\Desktop\Repo', filename)
The os module contains many useful methods for directory and path manipulation

Backslash character (\) has to be escaped in string literals.
This is wrong: '\'
This is correct: '\\' - this is a string containing one backslash
Therefore, this is wrong:
'C:\Program Files (x86)\LibreOffice 5\program\soffice.exe'
There is a trick!
String literals prefixed by r are meant for easier writing of regular expressions. One of their features is that backslash characters do not have to be escaped. So, this would be OK:
r'C:\Program Files (x86)\LibreOffice 5\program\soffice.exe'
However, that wont work for a string ending in backslash:
r'\' - this is a syntax error
So, this is also wrong:
r'C:\Users\A\Desktop\Repo\'
So, I would do the following:
import os
import subprocess
soffice = 'C:\\Program Files (x86)\\LibreOffice 5\\program\\soffice.exe'
outdir = 'C:\\Users\\A\\Desktop\\Repo\\'
full_path = os.path.join(outdir, filename)
subprocess.call([soffice,
'--headless',
'--convert-to', 'pdf',
'--outdir', outdir,
full_path])

The problem you have is that your raw string is ending with a single backslash. For reason I don't understand, this is not allowed. You can either double up the slash at the end:
r'C:\Users\A\Desktop\Repo\\'+filename
or use os.path.join(), which is the preferred method:
os.path.join(r'C:\Users\A\Desktop\Repo', filename)

To build on what zanseb said, use the os.path.join, but also \ is an escape character, so your string literal can't end with a \ as it would escape the ending quote.
import os
os.path.join(r'C:\Users\A\Desktop\Repo', filename)

To anyone else stumbling across this question, you can use \ to concatenate a Path object and str.
Use path.Path for paths compatible with both Unix and Windows (you can use it the same way as I've used pathlib.PureWindowsPath).
The only reason I'm using pathlib.PureWindowsPath is that the question asked specifically about Windows paths.
For example:
import pathlib
# PureWindowsPath enforces Windows path style
# for paths that work on both Unix and Windows use path.Path
base_dir = pathlib.PureWindowsPath(r'C:\Program Files (x86)\LibreOffice 5\program')
# elegant path concatenation
myfile = base_dir / "myfile.odt"
print(myfile)
>>> C:\Program Files (x86)\LibreOffice 5\program\myfile.odt

add library to code :
from pathlib import Path
when u want get current path without filename use this method :
print("Directory Path:", Path().absolute())
now you just need to add the file name to it :for example
mylink = str(Path().absolute())+"/"+"filename.etc" #str(Path().absolute())+"/"+"hello.txt"
If normally addes to the first path "r" character
for example: r"c://..."
You do not need to do here

You can also simply add the strings together. Personally I like this more.
filename = r"{}{}{}".format(dir, foldername, filename)

Related

Altering Windows file paths so that they use '/' instead of '\' [duplicate]

I am working in python and I need to convert this:
C:\folderA\folderB to C:/folderA/folderB
I have three approaches:
dir = s.replace('\\','/')
dir = os.path.normpath(s)
dir = os.path.normcase(s)
In each scenario the output has been
C:folderAfolderB
I'm not sure what I am doing wrong, any suggestions?
I recently found this and thought worth sharing:
import os
path = "C:\\temp\myFolder\example\\"
newPath = path.replace(os.sep, '/')
print(newPath) # -> C:/temp/myFolder/example/
Your specific problem is the order and escaping of your replace arguments, should be
s.replace('\\', '/')
Then there's:
posixpath.join(*s.split('\\'))
Which on a *nix platform is equivalent to:
os.path.join(*s.split('\\'))
But don't rely on that on Windows because it will prefer the platform-specific separator. Also:
Note that on Windows, since there is a current directory for each
drive, os.path.join("c:", "foo") represents a path relative to the
current directory on drive C: (c:foo), not c:\foo.
Try
path = '/'.join(path.split('\\'))
Path names are formatted differently in Windows. the solution is simple, suppose you have a path string like this:
data_file = "/Users/username/Downloads/PMLSdata/series.csv"
simply you have to change it to this: (adding r front of the path)
data_file = r"/Users/username/Downloads/PMLSdata/series.csv"
The modifier r before the string tells Python that this is a raw string. In raw strings, the backslash is interpreted literally, not as an escape character.
Sorry for being late to the party, but I wonder no one has suggested the pathlib-library.
pathlib is a module for "Object-oriented filesystem paths"
To convert from windows-style (backslash)-paths to forward-slashes (as typically for Posix-Paths) you can do so in a very verbose (AND platform-independant) fashion with pathlib:
import pathlib
pathlib.PureWindowsPath(r"C:\folderA\folderB").as_posix()
>>> 'C:/folderA/folderB'
Be aware that the example uses the string-literal "r" (to avoid having "\" as escape-char)
In other cases the path should be quoted properly (with double backslashes) "C:\\folderA\\folderB"
To define the path's variable you have to add r initially, then add the replace statement .replace('\\', '/') at the end.
for example:
In>> path2 = r'C:\Users\User\Documents\Project\Em2Lph\'.replace('\\', '/')
In>> path2
Out>> 'C:/Users/User/Documents/Project/Em2Lph/'
This solution requires no additional libraries
How about :
import ntpath
import posixpath
.
.
.
dir = posixpath.join(*ntpath.split(s))
.
.
This can work also:
def slash_changer(directory):
if "\\" in directory:
return directory.replace(os.sep, '/')
else:
return directory
print(slash_changer(os.getcwd()))
this is the perfect solution put the letter 'r' before the string that you want to convert to avoid all special characters likes '\t' and '\f'...
like the example below:
str= r"\test\hhd"
print("windows path:",str.replace("\\","\\\\"))
print("Linux path:",str.replace("\\","/"))
result:
windows path: \\test\\hhd
Linux path: /test/hhd

Backslash vs forwardslash when moving files in python

To move some files i am using this code:
import glob
import os
import shutil
list_of_files = glob.glob('C:/Users/user/staff/*')
latest_file = max(list_of_files, key=os.path.getctime)
print(latest_file)
filename= os.path.basename(latest_file)
shutil.move(latest_file, f"C:\\Users\\user\\test folder\\{filename}"
The code works and the file has moved but i would like to know if this actually matters:
The file which was moved is this:
C:/Users/user/staff\Aug-2021.csv
Notice the slash is now backward instead of forward. Does the orientation of slash matter or would matter in future when my code becomes more complicated(for best practices) or is this how it is suppose to work?
Both will work, but mixing slash and backslash is at least ugly. If you want to do something os independent, you can use os.sep to get the seperation character of your os.
>>> import os
>>> os.sep
'\\'
With this you could do something like
>>> os.sep.join(['foo','bar'])
'foo\\bar'
But you can also use os.path.join to build the path and let python handle that problem for you.
>>> import os
>>> os.path.join(os.getcwd(),'foo.bar')
'C:\\Users\\Me\\foo.bar'
Both foward or backslash are perfectly valid path separators. Also, it is a good practice to include 'r' before a path string:
r'C:\Users\user\staff\Aug-2021.csv'
The means your string will be treated as a raw string. You can see string literals reference here
Both works same but try to use \ slash to avoid 0.1 chance of error.
And I also get error of encoding so add r before the path eg : r"C:\\Users\\user\\test folder\\{filename}" .
Hope that answers the question.

A python function with a complicated argument

I have a function in a python code whose argument is as follows:
save_geometry(r"""C:\Users\User0\Documents\test.txt """)
I want to modify the argument and be able to save to a different path with a different filename:
filename = "geometries.txt "
filepath = "D:/AllData/"
filefullpath = filepath + filename
Could someone help me how I should pass filefullpath to save_geometry? If there were no r in the argument of save_geometry, it would be easy. But I don't know how to deal with this r.
The r"" construct just tells Python that whatever's in the string should be interpreted as raw data.
"qw\n" == 'qw\n'
r"qw\n" == 'qw\\n'.
It's used because the "\" path separator is also used for newlines and such. You can skip it when putting in the argument; save_geometry(filefullpath) should do what you expect.
Note that the canonical way of putting together paths is os.path.join
path = os.path.join("D:\\", "AllData", "geometries.txt")
User3757614's answer addresses your concern of the raw string notation, but succinctly all the r"" notation does is tell Python that the following string should not treat \ as an escape character, but as a literal backslash. This is important since "C:\new folder" is actually
C:
ew folder
Since \n is a newline.
You cans use the os module to split your string into a folder path and file name.
e.g.
import os
pathname = os.path.dirname('C:\Users\User0\Documents\test.txt') #C:\Users\User0\Documents
filename = os.path.basename('C:\Users\User0\Documents\test.txt') #test.txt
Though you'll need to modify your path string because your \s will be interpreted and newline bytes

How to convert back-slashes to forward-slashes?

I am working in python and I need to convert this:
C:\folderA\folderB to C:/folderA/folderB
I have three approaches:
dir = s.replace('\\','/')
dir = os.path.normpath(s)
dir = os.path.normcase(s)
In each scenario the output has been
C:folderAfolderB
I'm not sure what I am doing wrong, any suggestions?
I recently found this and thought worth sharing:
import os
path = "C:\\temp\myFolder\example\\"
newPath = path.replace(os.sep, '/')
print(newPath) # -> C:/temp/myFolder/example/
Your specific problem is the order and escaping of your replace arguments, should be
s.replace('\\', '/')
Then there's:
posixpath.join(*s.split('\\'))
Which on a *nix platform is equivalent to:
os.path.join(*s.split('\\'))
But don't rely on that on Windows because it will prefer the platform-specific separator. Also:
Note that on Windows, since there is a current directory for each
drive, os.path.join("c:", "foo") represents a path relative to the
current directory on drive C: (c:foo), not c:\foo.
Try
path = '/'.join(path.split('\\'))
Path names are formatted differently in Windows. the solution is simple, suppose you have a path string like this:
data_file = "/Users/username/Downloads/PMLSdata/series.csv"
simply you have to change it to this: (adding r front of the path)
data_file = r"/Users/username/Downloads/PMLSdata/series.csv"
The modifier r before the string tells Python that this is a raw string. In raw strings, the backslash is interpreted literally, not as an escape character.
Sorry for being late to the party, but I wonder no one has suggested the pathlib-library.
pathlib is a module for "Object-oriented filesystem paths"
To convert from windows-style (backslash)-paths to forward-slashes (as typically for Posix-Paths) you can do so in a very verbose (AND platform-independant) fashion with pathlib:
import pathlib
pathlib.PureWindowsPath(r"C:\folderA\folderB").as_posix()
>>> 'C:/folderA/folderB'
Be aware that the example uses the string-literal "r" (to avoid having "\" as escape-char)
In other cases the path should be quoted properly (with double backslashes) "C:\\folderA\\folderB"
To define the path's variable you have to add r initially, then add the replace statement .replace('\\', '/') at the end.
for example:
In>> path2 = r'C:\Users\User\Documents\Project\Em2Lph\'.replace('\\', '/')
In>> path2
Out>> 'C:/Users/User/Documents/Project/Em2Lph/'
This solution requires no additional libraries
How about :
import ntpath
import posixpath
.
.
.
dir = posixpath.join(*ntpath.split(s))
.
.
This can work also:
def slash_changer(directory):
if "\\" in directory:
return directory.replace(os.sep, '/')
else:
return directory
print(slash_changer(os.getcwd()))
this is the perfect solution put the letter 'r' before the string that you want to convert to avoid all special characters likes '\t' and '\f'...
like the example below:
str= r"\test\hhd"
print("windows path:",str.replace("\\","\\\\"))
print("Linux path:",str.replace("\\","/"))
result:
windows path: \\test\\hhd
Linux path: /test/hhd

os.walk() not picking up my file names

I'm trying to use a python script to edit a large directory of .html files in a loop. I'm having trouble looping through the filenames using os.walk(). This chunk of code just turns the html files into strings that I can work with, but the script does not even enter the loop, as if the files don't exist. Basically it prints point1 but never reaches point2. The script ends without an error message. The directory is set up inside the folder called "amazon", and there is one level of 20 subfolders inside of it with 20 html files in each of those.
Oddly the code works perfectly on a neighboring directory that only contains .txt files, but it seems like it's not grabbing my .html files for some reason. Is there something I don't understand about the structure of the for root, dirs, filenames in os.walk() loop? This is my first time using os.walk, and I've looked at a number of other pages on this site to try to make it work.
import os
rootdir = 'C:\filepath\amazon'
print "point1"
for root, dirs, filenames in os.walk(rootdir):
print "point2"
for file in filenames:
with open (os.path.join(root, file), 'r') as myfile:
g = myfile.read()
print g
Any help is much appreciated.
The backslash is used as an escape. Either double them, or use "raw strings" by putting a prefix "r" on it.
Example:
>>> 'C:\filepath\amazon'
'C:\x0cilepath\x07mazon'
>>> r'\x'
'\\x'
>>> '\x'
ValueError: invalid \x escape
Explanation: In Python, what does preceding a string literal with “r” mean?
You can avoid having to explicitly handle slashes of any sort by using os.path.join:
rootdir = os.path.join('C:', 'filepath', 'amazon')
Your problem is that you're using backslashes in your path:
>>> rootdir = 'C:\filepath\amazon'
>>> rootdir
'C:\x0cilepath\x07mazon'
>>> print(rootdir)
C:
ilepathmazon
Because Python strings use the backslash to escape special characters, in your rootdir the \f represents an ASCII Form Feed character, and the \a represents an ASCII Bell character.
You can either use a raw string (note the r before the apostrophe) to avoid this:
>>> rootdir = r'C:\filepath\amazon'
>>> rootdir
'C:\\filepath\\amazon'
>>> print(rootdir)
C:\filepath\amazon
... or just use regular slashes, which work fine on Windows anyway:
>>> rootdir = 'C:/filepath/amazon'
>>> rootdir
'C:/filepath/amazon'
>>> print(rootdir)
C:/filepath/amazon
As Huu Nguyen points out, it's considered good practice to construct paths using os.path.join() when possible ... that way you avoid the problem altogether:
>>> rootdir = os.path.join('C:', 'filepath', 'amazon')
>>> rootdir
'C:\\filepath\\amazon' # presumably ... I don't use Windows.
>>> print(rootdir)
C:\filepath\amazon
I had an issue that sounds similar to this with os.walk. The escape character (\) added to filepaths on Mac due to spaces in the path was causing the problem.
For example, the path:
/Volumes/MacHD/My Folder/MyFiles/...
when accessed via Terminal is shown as:
/Volumes/MacHD/My\ Folder/MyFiles/...
The solution was to read the path to a string and then create a new string that removed the escape characters, e.g:
# Ask user for directory tree to scan for master files
masterpathraw = raw_input("Specify directory of master files:")
# Clear escape characters from the path
masterpath = masterpathraw.replace('\\', '')
# Provide this path to os.walk
for fullpath, _, filenames in os.walk(masterpath):
# Do stuff

Categories

Resources