How to print relative path in file - python-3.x

So, I am trying to output folder & file structure to a txt file, using the below code. But I want to get relative paths outputed instead of absolute paths.
import os
absolute_path = os.path.dirname(__file__)
with open("output.txt", "w", newline='') as a:
for path, subdirs, files in os.walk(absolute_path):
a.write(path + os.linesep)
for filename in files:
a.write('\t%s\n' % filename)
For now this gives me something like this
C:\Users\User\OneDrive\bla\bla
C:\Users\User\OneDrive\bla\bla\folder1
file1.xxx
file2.xxx
file3.xxx
C:\Users\User\OneDrive\bla\bla\folder2
test1.txt
but I want to show only relative paths to where the script ran, not more
.\bla
.\bla\folder1
file1.xxx
file2.xxx
file3.xxx
.\bla\folder2
test1.txt
I have fiddled around a bit, but not getting to the solution, nor finding it here (or maybe I am not searching for the correct thing)
Any help would be appreciated

If you know the path to you current module, and you know the path of each file you find, and all your files will be in subdirectories of the current directory, you can calculate the relative path yourself.
Strings have the .replace(string_to_replace, replacement_value) method which will do this for you.
import os
absolute_path = os.path.dirname(__file__)
with open("output.txt", "w", newline='') as a:
for path, subdirs, files in os.walk(absolute_path):
a.write(path.replace(absolute_path, '.') + os.linesep)
for filename in files:
a.write('\t%s\n' % filename)

Beauty of python is, it os.path module ready for this kind of problems. You can use os.path.relpath() function
import os
absolute_path = os.path.dirname(__file__)
with open("output.txt", "w", newline='') as a:
for path, subdirs, files in os.walk(absolute_path):
a.write('.\\' + os.path.relpath(path + os.linesep, start=absolute_path))
for filename in files:
a.write('\t%s\n' % filename)
Here start parameter is used to current directory from where relative path should be resolved.

Related

how to rename files in a folder using pathlib in python?

I need help renaming .jpg files in my folder with the same prefix, 'cat_'. for example, 070.jpg should be renamed cat_070.jpg.
the files are located within the Cat folder:
from pathlib import Path
p = Path('C:\\Users\\me\\Jupiter_Notebooks\\Dataset\\Train\\Cat\\')
so I dont quite see how to do it? the below is wrong because it does not 'look into' the files in this directory.
p.rename(Path(p.parent, 'cat_' + p.suffix))
I have also unsuccessfully tried this:
import os
from os import rename
from os import listdir
# Get path
cwd = "C:\\Users\\me\\Jupiter_Notebooks\\Dataset\\Train\\Cat"
# Get all files in dir
onlyfiles = [f for f in listdir(cwd) if isfile(join(cwd, f))]
for file in onlyfiles:
# Get the current format
if file[-4:]==(".jpg"):
s = file[1]
# Change format and get new filename
s[1] = 'cat'
s = '_'.join(s)
# Rename file
os.rename(file, s)
print(f"Renamed {file} to {s}")
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'C:\\Users\\me\\Jupiter_Notebooks\\Dataset\\Train\\Cat\\'
how can I do it? sorry I'm really a beginner here.
How about:
from pathlib import Path
img_dir = Path('C:\\Users\\me\\Jupiter_Notebooks\\Dataset\\Train\\Cat\\') # path to folder with images
for img_path in img_dir.glob('*.jpg'): # iterate over all .jpg images in img_dir
new_name = f'cat_{img_path.stem}{img_path.suffix}' # or directly: f'cat_{img_path.name}'
img_path.rename(img_dir / new_name)
print(f'Renamed `{img_path.name}` to `{new_name}`')
pathlib also supports renaming files, so the os module is not even needed here.
use pathlib. Path. iterdir() to rename all files in a directory
1) for path in pathlib. Path("a_directory"). iterdir():
2) if path. is_file():
3) old_name = path. stem. original filename.
4) old_extension = path. suffix. original file extension.
5) directory = path. parent. ...
6) new_name = "text" + old_name + old_extension.
7) path. rename(pathlib.

Read folders in folder one by one

I am trying to read folders in one folder, and analyse the daten in these folders. My idea is to write two loop: one to choose the folder, one to analyse daten in the chosen folder. But i don't know how can i write the new path with iterate variable. line3 of this snapshot is my problem.
Thank you for any input.
If you only want to get the folders inside another folder (subfolders) and aren't interested in other files that could be in the root folder you could use:
import os
path = '...'
for file_folder in os.listdir(path):
path1 = os.path.join(path, file_folder)
if os.path.isdir(path1):
print(path1)
# do something
or
import glob
path = '...'
for folder in glob.glob(f'{path}/*/'):
# do something
In line number two & three from the image, you have written:
for file_folder in os.listdir(path):
path1 = 'path' + '\' + str(file_folder)
file_folder is like a temporary variable holding folder name value for a particular iteration.
It should instead be:
for file_folder in os.listdir(path):
path1 = 'path' + '\\' + file_folder

Open files where the filename may contain special characters on windows

I try to read all text files of a directory. The below code just works on linux. But I have problems reading files with special characters in it like: unsere-fotowand.html_tx_yag_pi1%5Bc142%5D%5BalbumUid%5D=1&tx_yag_pi1%5Bc142%5D%5BgalleryUid%5D=1&tx_yag_pi1%5Baction%5D=index&tx_yag_pi1%5Bcontroller%5D=Gallery&cHash=de647de667336c05d26cce3a7cb3a28a.txt on windows. I have tried things like filename.encode().decode('utf8') but this does not help.
import os
import sys
for r, d, f in os.walk(path):
for file in f:
if file.endswith('.txt'):
filename = os.path.join(r, file)
print(f'process file {filename}')
# throws file not found exception if tilename containts & or %
with open(filename, 'r', encoding="utf-8") as txtfile:
text = txtfile.read()
How can I make this work on linux and windows?

creating corresponding subfolders and writing a portion of the file in new files inside those subfolders using python

I have a folder named "data". It contains subfolders "data_1", "data_2", and "data_3". These subfolders contain some text files. I want to parse through all these subfolders and generate corresponding subfolders with the same name, inside another folder named "processed_data". I want to also generate corresponding files with "processed" as a prefix in the name and want to write all those lines from the original file where "1293" is there in the original files.
I am using the below code but not able to get the required result. Neither the subfolders "data_1", "data_2", and "data_3" nor the files are getting created
import os
folder_name=""
def pre_processor():
data_location="D:\data" # folder containing all the data
for root, dirs, files in os.walk(data_location):
for dir in dirs:
#folder_name=""
folder_name=dir
for filename in files:
with open(os.path.join(root, filename),encoding="utf8",mode="r") as f:
processed_file_name = 'D:\\processed_data\\'+folder_name+'\\'+'processed'+filename
processed_file = open(processed_file_name,"w", encoding="utf8")
for line_number, line in enumerate(f, 1):
if "1293" in line:
processed_file.write(str(line))
processed_file.close()
pre_processor()
You might need to elaborate on the issue you are having; e.g., are the files being created, but empty?
A few things I notice:
1) Your indentation is off (not sure if this is just a copy-paste issue though): the pre_processor function is empty, i.e. you are defining the function at the same level as the declaration, not inside of it.
try this:
import os
folder_name=""
def pre_processor():
data_location="D:\data" # folder containing all the data
for root, dirs, files in os.walk(data_location):
for dir in dirs:
#folder_name=""
folder_name=dir
for filename in files:
with open(os.path.join(root, filename), encoding="utf8",mode="r") as f:
processed_file_name = 'D:\\processed_data\\'+folder_name+'\\'+'processed'+filename
processed_file = open(processed_file_name,"w", encoding="utf8")
for line_number, line in enumerate(f, 1):
if "1293" in line:
processed_file.write(str(line))
processed_file.close()
pre_processor()
2) Check if the processed_data and sub_folders exist; if not, create them first as this will not do so.
Instead of creating the path to the new Folder by hand you could just replace the name of the folder.
Furthermore, you are not creating the subfolders.
This code should work but replace the Linux folder slashes:
import os
folder_name=""
def pre_processor():
data_location="data" # folder containing all the data
for root, dirs, files in os.walk(data_location):
for dir in dirs:
# folder_name=""
folder_name = dir
for filename in files:
joined_path = os.path.join(root, filename)
with open(joined_path, encoding="utf8", mode="r") as f:
processed_folder_name = root.replace("data/", 'processed_data/')
processed_file_name = processed_folder_name+'/processed'+filename
if not os.path.exists(processed_folder_name):
os.makedirs(processed_folder_name)
processed_file = open(processed_file_name, "w", encoding="utf8")
for line in f:
if "1293" in line:
processed_file.write(str(line))
processed_file.close()
pre_processor()

Exclude directory path if contains a given string

I wish to exclude any path from further action, if it includes a string.
Code example:
import os
Dirpath = input('What directory path e.g. C:/ ')
FileType = input('What Ext type to search for e.g. txt ')
for root, dirs, files in os.walk(Dirpath):
for file in files:
if file.endswith(FileType):
print(os.path.join(root, file))
I need to ignore any path with contains Dropbox e.g.
c:/Users\ljh36\Dropbox\Shared Folders\walk.tmp
Can any guidance be given please ?
An example in os.walk displays removing a dir named CVS
from the dirs list. You can adapt this to your code.
The forward slash in the input string can be changed to a
backslash by using r just before the string so you do not
need to escape it with an additional backslash.
import os
Dirpath = input(r'What directory path e.g. C:\ ')
FileType = input('What Ext type to search for e.g. txt ')
for root, dirs, files in os.walk(Dirpath):
# Remove 'Dropbox' from the list of dirs to walk.
if 'Dropbox' in dirs:
dirs.remove('Dropbox')
for file in files:
if file.endswith(FileType):
print(os.path.join(root, file))

Resources