Python Changing File path name - python

I want to replace my folder path by a string,I am getting an error.
I tried this :
a="ram"
my_list.to_csv(r'E:\'+str(a)+'\4\mani.csv' )

You made string concatenation mistake. try str.format to avoid such mistakes.
import os
a = "ram"
file_path = r'E:\{a}\4\mani.csv'.format(a=a)
directory = os.path.dirname(file_path)
os.makedirs(path, exist_ok=True)
my_list.to_csv(file_path)

>>> a = "ram"
>>> filename = 'mani.csv'
>>> absolute_path = os.path.join('E:', '4', a, filename)
>>> my_list.to_csv(absolute_path)

Related

importing filename and using regex to change the filename and save back

I have files with filenames as "lsud-ifgufib-1234568789.png" I want to rename this file as digits only which are followed by last "-" and then save them back in the folder.
Basically I want the final filename to be the digits that are followed by "-".
~ path = 'C:/Users/abc/downloads'
for filename in os.listdir(path):
r = re.compile("(\d+)")
newlist = filter(r.match, filename)
print(newlist)
~
How do I proceed further?
Assumptions:
You want to rename files if the file has a hyphen before the number.
The file may or may not have an extention.
If the file has an extention, preserve it.
Then would you please try the following:
import re, os
path = 'C:/Users/abc/downloads'
for filename in os.listdir(path):
m = re.search(r'.*-(\d+.*)', filename)
if m:
os.rename(os.path.join(path, filename), os.path.join(path, m.group(1)))
You could try a regex search followed by a path join:
import re
import os
path = 'C:/Users/abc/downloads'
for filename in os.listdir(path):
os.rename(filename, os.path.join(path, re.search("\d+(?=\D+?$)", filename).group()))
import re
import pathlib
fileName = "lsud-ifgufib-1234568789.png"
_extn = pathlib.Path(fileName).suffix
_digObj = re.compile(r'\d+')
digFileName = ''.join(_digObj.findall(fileName))
replFileName = digFileName + _extn

rename files in a folder then move them to another folder

Ive got a bunch of files in a folder all with the same extension:
[movie] Happy feet 2021-04-01 22-00-00.avi
[movie] Dogs Life 2021-06-01 22-03-50.avi
etc
would like to rename the start and end to:
Happy feet.avi
Dogs Life.avi
etc
Here is what I have so far:
import shutil
import os
source_dir = r"C:\\Users\\ED\\Desktop\\testsource"
target_dir = r"C:\\Users\\ED\\Desktop\\testdest"
data = os.listdir(source_dir)
print(data)
new_data = [file[8:].split(' 2021')[0] + '.txt' for file in data]
print(new_data)
for file in data:
os.replace(data, [file[8:].split(' 2021')[0] + '.txt')
for file_name in data:
shutil.move(os.path.join(source_dir, file_name), target_dir)
Im having trouble with the os.rename() part after I printed it out.
You can use (tested):
from glob import glob
import re
import shutil
import os
src = "C:/Users/ED/Desktop/testsource"
dst = "C:/Users/ED/Desktop/testdest"
for f in glob(f"{src}/**"):
fn = os.path.basename(f)
new_fn = re.sub(r"^\[.*?\](.*?) \d{4}-\d{2}-\d{2} \d{2}-\d{2}-\d{2}(\..*?)$", r"\1\2", fn).strip()
shutil.move(f, f"{dst}/{new_fn}")
For python 2:
for f in glob(src+"/**"):
fn = os.path.basename(f)
new_fn = re.sub(r"^\[.*?\](.*?) \d{4}-\d{2}-\d{2} \d{2}-\d{2}-\d{2}(\..*?)$", r"\1\2", fn).strip()
shutil.move(f, dst+"/"+new_fn)
If you're using r"foobar" I don't think you have to escape the \s, do you?
So it should be
source_dir = r"C:\Users\ED\Desktop\testsource"
target_dir = r"C:\Users\ED\Desktop\testdest"
So, there are some issues with the code.
In the for loop for os.replace(), you are passing the entire list of data as src which is ['Dogs Life 2021-06-01 22-03-50.avi', '2021-04-01 22-00-00.avi']
Instead what I did is use file in the loop.
Also with the statement os.replace(data, [file[8:].split(' 2021')[0] + '.txt') your variables inside os.replace() would be a list item, so I changed it string.
One last thing is that you need to use the full file path in the os.move() unless the files are in the current working directory
I didn't touch the shutil.move() function. Let me know if this works.
import shutil
import os
source_dir = r"C:\\Users\\ED\\Desktop\\testsource"
target_dir = r"C:\\Users\\ED\\Desktop\\testdest"
data = os.listdir(source_dir)
print(data)
new_data = [file[8:].split(' 2021')[0] + '.txt' for file in data]
print(new_data)
for file in data:
os.replace('C:\\Users\\ED\\Desktop\\testsource\\'+str(file), 'C:\\Users\\ED\\Desktop\\testsource\\'+str(file[8:].split(' 2021')[0] + '.txt'), src_dir_fd=None, dst_dir_fd=None)

How to get filename without some special extensions in python

I have a file that has some special extension. Sometime it is '.exe', or 'exe.gz' or 'exe.tar.gz'...I want to get the filename only. I am using the below code to get filename abc but it cannot work for all cases
import os
filename = 'abc.exe'
base = os.path.basename(filename)
print(os.path.splitext(base)[0])
filename = 'abc.exe.gz'
base = os.path.basename(filename)
print(os.path.splitext(base)[0])
Note that, I knew the list of extensions such as ['.exe','exe.gz','exe.tar.gz', '.gz']
You can just split with the . char and take the first element:
>>> filename = 'abc.exe'
>>> filename.split('.')[0]
'abc'
>>> filename = 'abc.exe.gz'
>>> filename.split('.')[0]
'abc'
How about a workaround like this?
suffixes = ['.exe','.exe.gz','.exe.tar.gz', '.gz']
def get_basename(filename):
for suffix in suffixes:
if filename.endswith(suffix):
return filename[:-len(suffix)]
return filename

separate filename after underlining _ os.path

In my path /volume1/xx/ are several files with this character A_test1.pdf, B_test2.pdf, ...I want to seperate the test1 part without path and .pdf.
Im newbie so I tried first with full name
but I got only the "*.pdf" as a text.
What is wrong with the path oder placeholder * ?
splitname = os.path.basename('/volume1/xx/*.pdf')
Edit
I got 2019-01-18_RG-Telekom[] from orign ReT_march - I want 2019-01-18_RG-Telekom_march (text after underlining) xx is a folder
here is the whole code:
#!/usr/bin/env python3
import datetime
import glob
import os
import os.path
SOURCE_PATH = '/volume1/xx'
TARGET_PATH = os.path.join(SOURCE_PATH, 'DMS')
def main():
today = datetime.date.today()
splitnames = [os.path.basename(fpath) for fpath in glob.glob("./xx/*.pdf")]
for prefix, name_part in [
('ReA', 'RG-Amazon'),
('GsA', 'GS-Amazon'),
('ReT', 'RG-Telekom'),
('NoE', 'Notiz-EDV'),
]:
filenames = glob.iglob(os.path.join(SOURCE_PATH, prefix + '*.pdf'))
for old_filename in filenames:
new_filename = os.path.join(TARGET_PATH, '{}_{}_{}.pdf'.format(today, name_part, splitnames))
os.rename(old_filename, new_filename)
if __name__ == '__main__':
main()
Use glob, os.path don't know how to process masks, but glob.glob works:
splitnames = [os.path.basename(fpath) for fpath in glob.glob("./**/*.txt")]
splitnames
Out:
['A_test1.pdf', 'B_test2.pdf']
Output of the glob:
glob.glob("./**/*.txt")
Out:
['./some_folder/A_test1.pdf', './another_folder/B_test2.pdf']
Apply os.path.basename to this list and extract basenames, as it shown above.
Edit
If xx in the path volume1/xx/ is just a folder name, not a mask, you should use following expression:
splitnames = [os.path.basename(fpath) for fpath in glob.glob("./xx/*.txt")]
because ./**/ is expression which masks a folder name and it's unnecessary that case.

Python: change part (single directory name) of path

What would be the best way to change a single directory name (only the first occurence) within a path?
Example:
source_path = "/path/to/a/directory/or/file.txt"
target_path = "/path/to/different/directory/or/file.txt"
I this case, the instruction would be: "replace the first directory of the name 'a' with a directory of the name 'different'"
I can think of methods where I would split up the path in its single parts first, then find the first "a", replace it and join it again. But I wonder if there is a more elegant way to deal with this. Maybe a built-in python function.
There is a function called os.path.split that can split a path into the final part and all leading up to it but that's the closest your going to get. Therefore the most elegant thing we can do is create a function that calls that continuously:
import os, sys
def splitall(path):
allparts = []
while 1:
parts = os.path.split(path)
if parts[0] == path: # sentinel for absolute paths
allparts.insert(0, parts[0])
break
elif parts[1] == path: # sentinel for relative paths
allparts.insert(0, parts[1])
break
else:
path = parts[0]
allparts.insert(0, parts[1])
return allparts
Then you could use it like this, joining back together with os.path.join:
>>> source_path = '/path/to/a/directory/or/file'
>>> temp = splitall(source_path)
>>> temp
['path', 'to', 'a', 'directory', 'or', 'file']
>>> temp[2] = 'different'
>>> target_path = os.path.join(*temp)
>>> target_path
'path/to/different/directory/or/file'
If I understand what you want to say, you want this:
source_path = "/path/to/a/directory/or/file.txt"
target_path = source_path.replace("/a/", "/different/", 1)
print target_path
Use https://docs.python.org/3/library/pathlib.html#module-pathlib:
>>> from pathlib import PurePath
>>> import os
>>> path = PurePath("/path/to/a/directory/or/file.txt")
>>> path.parts
('/', 'path', 'to', 'a', 'directory', 'or', 'file.txt')
>>> a_idx = -1
>>> for idx,part in enumerate(path.parts):
... if part == 'a':
... a_idx = idx
... break
...
>>> a_idx
3
>>> pre_path = os.path.join(*path.parts[:a_idx])
>>> post_path = os.path.join(*path.parts[a_idx+1:])
>>> new_path = os.path.join(pre_path, 'different', post_path)
>>> new_path
'/path/to/different/directory/or/file.txt'
In case you don't know the name of the directory, but only its index:
from pathlib import Path
source_path = Path("/path/to/a/directory/or/file.txt")
unknown_name = source.parts[3] # position including root
target_path = "/".join([part if part != unknown_name else "different" for part in source.parts])[1:]
In case you know the name of the directory but not its index, almost the same:
from pathlib import Path
source = Path("/path/to/a/directory/or/file.txt")
src_parts = source.parts
unknown_index = src_parts.index('a')
target_path = "/".join([src_parts[part] if part != unknown_index else "different" for part in range(len(src_parts))])[1:]

Categories