Python os.path.join absolute path on Linux - python

I have a file path like this:
file_name = full_path + env + '/filename.txt'
in which:
full_path is '/home/louis/key-files/
env is 'prod'
=> file name is '/home/louis/key-files/prod/filename.txt'
I want to use os.path.join
file_name = os.path.abspath(os.path.join(full_path, env, '/filename.txt'))
But the returned result is only: file_name = '/filename.txt'
How can I get the expected result like above?
Thanks

Since your last component begins with a slash, it is taken as starting from the root, so os.path.join just removes everything else. Try without the leading slash instead:
os.path.join(full_path, env, 'filename.txt')
Note you probably don't need abspath here.

Related

Find absolute path of a file in python when knowing the last part of the path and the base directory?

Using python, I have the last parts of paths to existing files, like that:
sub_folder1/file1.txt
sub_folder2/file120.txt
sub_folder78/file99.txt
Note, that these paths are not the relative paths to the current folder I am working in, e.g., this pandas.read_csv('sub_folder1/file1.txt') would through a non-existing-file error. Nevertheless, I know all the files have the same base directory base_dir, but I don't know the absolute path. This means a file could be located like this:
base_dir/inter_folder1/sub_folder1/file1.txt
Or like this:
base_dir/inter_folder7/inter_folder4/.../sub_folder1/file1.txt
Is there a function that returns the absolute path, when given the last part of the path and the base directory of a file (or equivalently, finding the intermediate folders)? Should be looking like that:
absolut_path = some_func(end_path='bla/bla.txt', base_dir='BLAH')
I thought pathlib might have a solution, but couldn't find anything there. Thanks
I need this to do something like the below:
for end_path in list_of_paths:
full_path = some_func(end_path=end_path, base_dir='base_dir')
image = cv2.imread(full_path)
This should be fairly easy to implement from pathlib:
from pathlib import Path
def find(end_path: str, base_dir: str):
for file in Path(base_dir).rglob("*"):
if str(file).endswith(end_path):
yield file
This is a generator, to match the pathlib interface; as such it will yield pathlib.PosixPath objects. It will also find all matching files, for example:
[str(f) for f in find(end_path="a.txt", base_dir="my_dir")]
# creates:
# ['my_dir/a.txt', 'my_dir/sub_dir/a.txt']
If you just want the first value you can just return the first item:
def find_first(end_path: str, base_dir: str):
for file in Path(base_dir).rglob("*"):
if str(file).endswith(end_path):
return str(file)
abs_path = find_first(end_path="a.txt", base_dir="my_dir")
A better function that would improve the lookup:
from pathlib import Path
def find(pattern, suffixes, base_dir):
for file in Path(base_dir).rglob(pattern):
if any(str(file).endswith(suffix) for suffix in suffixes):
yield str(file)
base_dir = "base_directory"
suffixes = [
'sub_folder1/file1.txt',
'sub_folder2/file120.txt',
'sub_folder78/file99.txt',
]
for full_path in find(pattern="*.txt", suffixes=suffix, base_dir=base_dir):
image = cv2.imread(full_path)
You need to search for the sub-folder within the base folder e.g,
import os
for dirpath, dirnames, files in os.walk(os.path.abspath(base_dir)):
if dirpath.endswith(subfolder1):
print(dirpath)
You might want to also make sure that the file exists in that folder using:
if dirpath.endswith("subfolder1") and "file1.txt" in files:
print(dirpath)

Get file path without file name

Given a file path
/path/to/some/file.jpg
How would I get
/path/to/some
I'm currently doing
fullpath = '/path/to/some/file.jpg'
filepath = '/'.join(fullpath.split('/')[:-1])
But I think it is open to errors
With os.path.split:
dirname, fname = os.path.split(fullpath)
Per the docs:
Split the pathname path into a pair, (head, tail) where tail is the
last pathname component and head is everything leading up to that. The
tail part will never contain a slash; if path ends in a slash, tail
will be empty. If there is no slash in path, head will be empty.
os.path is always the module suitable for the platform that the code is running on.
Please try this
fullpath = '/path/to/some/file.jpg'
import os
os.path.dirname(fullpath)
Using pathlib you can get the path without the file name using the .parent attribute:
from pathlib import Path
fullpath = Path("/path/to/some/file.jpg")
filepath = str(fullpath.parent) # /path/to/some/
This handles both UNIX and Windows paths correctly.
With String rfind method.
fullpath = '/path/to/some/file.jpg'
index = fullpath.rfind('/')
fullpath[0:index]

How to check parameters for os.makedirs?

I use this code for create folder for users:
work_path = '/tmp/'
os.umask(0000)
for i in user:
if not os.path.exists(work_path + i):
try:
os.makedirs(work_path + i, 0777)
When I set work_path = '/tmp/' - my code work perfect.
But when I type for mistake work_path = '/tmp' I got not what expected )))
Question: how can I check my path have backslash, or maybe how can I create folders for another way ?
Use os.path.join:
Join one or more path components intelligently. The return value is the concatenation of path and any members of *paths with exactly one directory separator (os.sep) following each non-empty part except the last, meaning that the result will only end in a separator if the last part is empty. If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component.
os.makedirs(os.path.join(work_path,i))
So in your code join the path once then use the joined path:
for i in user:
pth = os.path.join(work_path, i)
if not os.path.exists(pth):
try:
os.makedirs(pth, 0777)
You can use just the expression
work_path[-1] == '/'
If it is true you have a backslash

Fastest way to replace elements of a file's path and extension?

Given the path of a file:
file = "/directory/date/2011/2009-01-11 This is a file's path/file.jpg"
How can I quickly replace it with:
new_file = "/newdirectory/date/2011/2009-01-11 This is a file's path/file.MOV"
Changing both directory for "newdirectory" and ".jpg" for ".MOV"
Well this can be done in different way's, but this is how I would do
First change the extension. This can be easily done via os.path.splitext something like
path = "/directory/date/2011/2009-01-11 This is a file's path/file.jpg"
new_file=os.path.splitext(path)[0]+".MOV"
This gives the path as
"/directory/date/2011/2009-01-11 This is a file's path/file.MOV"
Now to change the directory to newdirectory, we can use str.split, with maxsplit option.
new_file=new_file.split('/',2)
and finally use join, replacing the second item in the list with your favorite directory with '/' as the delimiter
new_file = '/'.join([new_file[0],"newdirectory",new_file[2]])
So finally we have
"/newdirectory/date/2011/2009-01-11 This is a file's path/file.MOV"
So to summarize, it boils down to three lines
new_file=os.path.splitext(path)[0]+".MOV"
new_file=new_file.split('/',2)
new_file = '/'.join([new_file[0],"newdirectory",new_file[2]])
I would make use of os.sep
import os
path = "/directory/date/2011/2009-01-11 This is a file's path/file.jpg"
path = os.path.splitext(path)[0] + '.mov'
path = path.split(os.sep, 2)
path[1] = 'newdirectory'
path = os.sep.join(path)
print path
Result:
/newdirectory/date/2011/2009-01-11 This is a file's path/file.mov

How to rename a file using Python

I want to change a.txt to b.kml.
Use os.rename:
import os
os.rename('a.txt', 'b.kml')
Usage:
os.rename('from.extension.whatever','to.another.extension')
File may be inside a directory, in that case specify the path:
import os
old_file = os.path.join("directory", "a.txt")
new_file = os.path.join("directory", "b.kml")
os.rename(old_file, new_file)
As of Python 3.4 one can use the pathlib module to solve this.
If you happen to be on an older version, you can use the backported version found here
Let's assume you are not in the root path (just to add a bit of difficulty to it) you want to rename, and have to provide a full path, we can look at this:
some_path = 'a/b/c/the_file.extension'
So, you can take your path and create a Path object out of it:
from pathlib import Path
p = Path(some_path)
Just to provide some information around this object we have now, we can extract things out of it. For example, if for whatever reason we want to rename the file by modifying the filename from the_file to the_file_1, then we can get the filename part:
name_without_extension = p.stem
And still hold the extension in hand as well:
ext = p.suffix
We can perform our modification with a simple string manipulation:
Python 3.6 and greater make use of f-strings!
new_file_name = f"{name_without_extension}_1"
Otherwise:
new_file_name = "{}_{}".format(name_without_extension, 1)
And now we can perform our rename by calling the rename method on the path object we created and appending the ext to complete the proper rename structure we want:
p.rename(Path(p.parent, new_file_name + ext))
More shortly to showcase its simplicity:
Python 3.6+:
from pathlib import Path
p = Path(some_path)
p.rename(Path(p.parent, f"{p.stem}_1_{p.suffix}"))
Versions less than Python 3.6 use the string format method instead:
from pathlib import Path
p = Path(some_path)
p.rename(Path(p.parent, "{}_{}_{}".format(p.stem, 1, p.suffix))
import shutil
shutil.move('a.txt', 'b.kml')
This will work to rename or move a file.
os.rename(old, new)
This is found in the Python docs: http://docs.python.org/library/os.html
As of Python version 3.3 and later, it is generally preferred to use os.replace instead of os.rename so FileExistsError is not raised if the destination file already exists.
assert os.path.isfile('old.txt')
assert os.path.isfile('new.txt')
os.rename('old.txt', 'new.txt')
# Raises FileExistsError
os.replace('old.txt', 'new.txt')
# Does not raise exception
assert not os.path.isfile('old.txt')
assert os.path.isfile('new.txt')
See the documentation.
Use os.rename. But you have to pass full path of both files to the function. If I have a file a.txt on my desktop so I will do and also I have to give full of renamed file too.
os.rename('C:\\Users\\Desktop\\a.txt', 'C:\\Users\\Desktop\\b.kml')
One important point to note here, we should check if any files exists with the new filename.
suppose if b.kml file exists then renaming other file with the same filename leads to deletion of existing b.kml.
import os
if not os.path.exists('b.kml'):
os.rename('a.txt','b.kml')
import os
# Set the path
path = 'a\\b\\c'
# save current working directory
saved_cwd = os.getcwd()
# change your cwd to the directory which contains files
os.chdir(path)
os.rename('a.txt', 'b.klm')
# moving back to the directory you were in
os.chdir(saved_cwd)
Using the Pathlib library's Path.rename instead of os.rename:
import pathlib
original_path = pathlib.Path('a.txt')
new_path = original_path.rename('b.kml')
Here is an example using pathlib only without touching os which changes the names of all files in a directory, based on a string replace operation without using also string concatenation:
from pathlib import Path
path = Path('/talend/studio/plugins/org.talend.designer.components.bigdata_7.3.1.20200214_1052\components/tMongoDB44Connection')
for p in path.glob("tMongoDBConnection*"):
new_name = p.name.replace("tMongoDBConnection", "tMongoDB44Connection")
new_name = p.parent/new_name
p.rename(new_name)
import shutil
import os
files = os.listdir("./pics/")
for key in range(0, len(files)):
print files[key]
shutil.move("./pics/" + files[key],"./pics/img" + str(key) + ".jpeg")
This should do it. python 3+
How to change the first letter of filename in a directory:
import os
path = "/"
for file in os.listdir(path):
os.rename(path + file, path + file.lower().capitalize())
then = os.listdir(path)
print(then)
If you are Using Windows and you want to rename your 1000s of files in a folder then:
You can use the below code. (Python3)
import os
path = os.chdir(input("Enter the path of the Your Image Folder : ")) #Here put the path of your folder where your images are stored
image_name = input("Enter your Image name : ") #Here, enter the name you want your images to have
i = 0
for file in os.listdir(path):
new_file_name = image_name+"_" + str(i) + ".jpg" #here you can change the extention of your renmamed file.
os.rename(file,new_file_name)
i = i + 1
input("Renamed all Images!!")
os.chdir(r"D:\Folder1\Folder2")
os.rename(src,dst)
#src and dst should be inside Folder2
import os
import re
from pathlib import Path
for f in os.listdir(training_data_dir2):
for file in os.listdir( training_data_dir2 + '/' + f):
oldfile= Path(training_data_dir2 + '/' + f + '/' + file)
newfile = Path(training_data_dir2 + '/' + f + '/' + file[49:])
p=oldfile
p.rename(newfile)
You can use os.system to invoke terminal to accomplish the task:
os.system('mv oldfile newfile')

Categories

Resources