How to replace a part of a File Path in Python - python

import os.path
original = input(str("Filepath:"))
filename = os.path.basename(original)
print(filename)
target = r'C:\Users\Admin\Desktop\transfer\filename'
path = filename.replace('filename', filename)
print(path)
I have a problem with getting new target path... I need to copy original file and paste it to new directory, that is always the same and the name must stay the same as it was in previous directory, I was trying to do it by code on top but it doesn't work, only thing I need to know is how to replace name of the Path file at the end. (Example: r'C:\Users\Admin\Desktop\Directory2\***' and replace *** with filename of first file)

Considering your code, if you want to change C:\Users\Admin\Desktop\transfer\filename into C:\Users\Admin\Desktop\transfer\{new filename} you need to call replace() function on «target» variable, not on the «filename» variable.
So your code would look something like:
import os.path
original = input(str("Filepath:"))
filename = os.path.basename(original)
target = r'C:\Users\Admin\Desktop\transfer\filename'
path = target.replace('filename', filename)
On entering D:\Documents\program.py, the output is C:\Users\Admin\Desktop\transfer\program.py

Related

Change filename prefix in Path PosixPath object

I need to change a prefix for a current file.
An example would look as follows:
from pathlib import Path
file = Path('/Users/my_name/PYTHON/Playing_Around/testing_lm.py')
# Current file with destination
print(file)
# Prefix to be used
file_prexif = 'A'
# Hardcoding wanted results.
Path('/Users/my_name/PYTHON/Playing_Around/A_testing_lm.py')
As can be seen hardcoding it is easy. However is there a way to automate this step?
There is a pseudo - idea of what I want to do:
str(file).split('/')[-1] = str(file_prexif) + str('_') + str(file).split('/')[-1]
I only want to change last element of PosixPath file. However it is not possible to change only last element of string
file.stem accesses the base name of the file without extension.
file.with_stem() (added in Python 3.9) returns an updated Path with a new stem:
from pathlib import Path
file = Path('/Users/my_name/PYTHON/Playing_Around/testing_lm.py')
print(file.with_stem(f'A_{file.stem}'))
\Users\my_name\PYTHON\Playing_Around\A_testing_lm.py
Use file.parent to get the parent of the path and file.name to get the final path component, excluding the drive and root.
from pathlib import Path
file = Path('/Users/my_name/PYTHON/Playing_Around/testing_lm.py')
file_prexif_lst = ['A','B','C']
for prefix in file_prexif_lst:
p = file.parent.joinpath(f'{prefix}_{file.name}')
print(p)
/Users/my_name/PYTHON/Playing_Around/A_testing_lm.py
/Users/my_name/PYTHON/Playing_Around/B_testing_lm.py
/Users/my_name/PYTHON/Playing_Around/C_testing_lm.py

python check if the folder content existed

The purpose of this code is:
Read a csv file which contains a column for a list of file names
here is the csv file:
https://drive.google.com/open?id=0B5bJvxM9TZkhVGI5dkdLVzAyNTA
Then check a specific folder to check if the files exist or not
If its found a file is not in the list delete it
here is the code:
import pandas as pd
import os.path
data = pd.read_csv('data.csv')
names = data['title']
path = "C:\\Users\\Sayed\\Desktop\\Economic Data"
for file in os.listdir(path):
os.path.exists(file)
print(file)
file = os.path.join(path, file)
fileName = os.path.splitext(file)
if fileName not in names:
print('error')
os.remove(file)
I modified the first code, and this is the new code and I got no error but the simply delete all the files in the directory
os.chdir does not return anything, so assigning the result to path means that path has None, which causes the error.
Since you're using pandas, here's a little trick to speed this up using pd.Series.isin.
root = "C:\Users\Sayed\Desktop\Economic Data"
files = os.listdir(root)
for f in data.loc[~data['title'].isin(files), 'title'].tolist():
try:
os.remove(os.path.join(root, f))
except OSError:
pass
Added a try-except check in accordance with EAFP (since I'm not doing an os.path.exists check here). Alternatively, you could add a filter based on existence using pd.Series.apply:
m = ~data['title'].isin(files) & data['title'].apply(os.path.exists)
for f in data.loc[m, 'title'].tolist():
os.remove(os.path.join(root, f))
Your path is the return value of the os.chdir() call. Which is obviously None.
You want to set path to the string representing the path ... leave the chdir out.

Rename files in multiple directories

I have files named the same in multiple directories. I wanted to change their names, so they would correspond to the unique id of the directory that they are in.
'*' represents unique identifier, like '067' for example
The filename is always 'NoAdapter_len25.truncated_sorted.fastq'
I wanted the filename in each directory to be '*NoAdapter_len25.truncated_sorted.fastq', where * stands for the unique identifier
Here is the the error I'm getting:
Traceback (most recent call last):
File "change_names.py", line 19, in <module>
rename(name, new_name)
TypeError: Can't convert '_io.TextIOWrapper' object to str implicitly
Here's the code that produces it:
from glob import glob
import re
from os import rename
#path = "/home/users/screening/results_Sample_*_hg38_hg19/N*"
files = glob(path)
for f in files:
with open(f) as name:
sample_id = f.partition('results_')[-1].rpartition('hg38_hg19')[0]
#print(sample_id)
back = f[-38:]
new_name = sample_id + back
rename(name, new_name)
You have a few problems:
You're opening a file for no apparent reason (it confirms the file exists and is readable at open time, but even with an open handle, the name could be moved or deleted between that and the rename, so you aren't preventing any race conditions)
You're passing the opened file object to os.rename, but os.rename takes str, not file-like objects
You're doing a lot of "magic" manipulations of the path, instead of using appropriate os.path functions
Try this to simplify the code. I included some inline comments when I'm doing what your example does, but it doesn't make a lot of sense (or it's poor form):
for path in files: # path, not f; f is usually placeholder for file-like object
filedir, filename = os.path.split(path)
parentdir = os.path.dirname(filedir)
# Strip parentdir name to get 'Sample_*_' per provided code; is this what you wanted?
# Question text seems like you only wanted the '*' part.
sample_id = parentdir.replace('results_', '').replace('hg38_hg19', '')
# Large magic numbers are code smell; if the name is a fixed name,
# just use it directly as a string literal
# If the name should be "whatever the file is named", use filename unsliced
# If you absolutely need a fixed length (to allow reruns or something)
# you might do keepnamelen = len('NoAdapter_len25.truncated_sorted.fastq')
# outside the loop, and do f[-keepnamelen:] inside the loop so it's not
# just a largish magic number
back = filename[-38:]
new_name = sample_id + back
new_path = os.path.join(filedir, new_name)
rename(path, new_path)
You feed rename a file (name) and a filename, it needs two filenames. To get from a file to its filename, you can do this
old_filename = os.path.abspath(name.name)

Python converting url into directory

I am trying to convert a url like "www.example.com/images/dog.png" into directories from the current directory.
So I get a folder named "www.example.com", inside that "images" and finally inside that the file saved as "dog.png"
I've tried using urllib.url2pathname(path) but it keeps appending P:\ to the start of it.
You can use os.makedirs() to create the directory tree, but that will fail if the final directory already exists. So you can test if it exists before attempting to create the directory tree, or use try: ... except OSError:. In Python 3 you can supply an exist_ok parameter to over-ride this behaviour, see the Python docs of os.makedirs for further info.
#!/usr/bin/env python
import os
cwd = os.getcwd()
url = "www.example.com/images/dog.png"
fullname = os.path.join(cwd, url)
path, basename = os.path.split(fullname)
if not os.path.exists(path):
os.makedirs(path)
with open(fullname, 'w') as f:
f.write('test\n')
If your system doesn't support directory names containing periods you can translate them to another character, eg _, like this:
fullname = fullname.replace('.', '_')
(just insert this after the fullname = os.path.join(cwd, url) line).
And as jwilner mentions in the comments, it's more efficient to use
path = os.path.dirname
than path, basename = os.path.split(fullname) if you don't need the base component of the file name (in this example "dog.png").

How to extract a file within a folder within a zip?

I need to extract a file called Preview.pdf from a folder called QuickLooks inside of a zip file.
Right now my code looks a little like this:
with ZipFile(newName, 'r') as newName:
newName.extract(\QuickLooks\Preview.pdf)
newName.close()
(In this case, newName has been set equal to the full path to the zip).
It's important to note that the backslash is correct in this case because I'm on Windows.
The code doesn't work; here's the error it gives:
Traceback (most recent call last):
File "C:\Users\Asit\Documents\Evam\Python_Scripts\pageszip.py", line 18, in <module>
ZF.extract("""QuickLooks\Preview.pdf""")
File "C:\Python33\lib\zipfile.py", line 1019, in extract
member = self.getinfo(member)
File "C:\Python33\lib\zipfile.py", line 905, in getinfo
'There is no item named %r in the archive' % name)
KeyError: "There is no item named 'QuickLook/Preview.pdf' in the archive"
I'm running the Python script from inside Notepad++, and taking the output from its console.
How can I accomplish this?
Alternatively, how could I extract the whole QuickLooks folder, move out Preview.pdf, and then delete the folder and the rest of it's contents?
Just for context, here's the rest of the script. It's a script to get a PDF of a .pages file. I know there are bonified converters out there; I'm just doing this as an excercise with some sort of real-world application.
import os.path
import zipfile
from zipfile import *
import sys
file = raw_input('Enter the full path to the .pages file in question. Please note that file and directory names cannot contain any spaces.')
dir = os.path.abspath(os.path.join(file, os.pardir))
fileName, fileExtension = os.path.splitext(file)
if fileExtension == ".pages":
os.chdir(dir)
print (dir)
fileExtension = ".zip"
os.rename (file, fileName + ".zip")
newName = fileName + ".zip" #for debugging purposes
print (newName) #for debugging purposes
with ZipFile(newName, 'w') as ZF:
print("I'm about to list names!")
print(ZF.namelist()) #for debugging purposes
ZF.extract("QuickLook/Preview.pdf")
os.rename('Preview.pdf', fileName + '.pdf')
finalPDF = fileName + ".pdf"
print ("Check out the PDF! It's located at" + dir + finalPDF + ".")
else:
print ("Sorry, this is not a valid .pages file.")
sys.exit
I'm not sure if the import of Zipfile is redundant; I read on another SO post that it was better to use from zipfile import * than import zipfile. I wasn't sure, so I used both. =)
EDIT: I've changed the code to reflect the changes suggested by Blckknght.
Here's something that seems to work. There were several issues with your code. As I mentioned in a comment, the zipfile must be opened with mode 'r' in order to read it. Another is that zip archive member names always use forward slash / characters in their path names as separators (see section 4.4.17.1 of the PKZIP Application Note). It's important to be aware that there's no way to extract a nested archive member to a different subdirectory with Python's currentzipfilemodule. You can control the root directory, but nothing below it (i.e. any subfolders within the zip).
Lastly, since it's not necessary to rename the .pages file to .zip — the filename you passZipFile() can have any extension — I removed all that from the code. However, to overcome the limitation on extracting members to a different subdirectory, I had to add code to first extract the target member to a temporary directory, and then copy that to the final destination. Afterwards, of course, this temporary folder needs to deleted. So I'm not sure the net result is much simpler...
import os.path
import shutil
import sys
import tempfile
from zipfile import ZipFile
PREVIEW_PATH = 'QuickLooks/Preview.pdf' # archive member path
pages_file = input('Enter the path to the .pages file in question: ')
#pages_file = r'C:\Stack Overflow\extract_test.pages' # hardcode for testing
pages_file = os.path.abspath(pages_file)
filename, file_extension = os.path.splitext(pages_file)
if file_extension == ".pages":
tempdir = tempfile.gettempdir()
temp_filename = os.path.join(tempdir, PREVIEW_PATH)
with ZipFile(pages_file, 'r') as zipfile:
zipfile.extract(PREVIEW_PATH, tempdir)
if not os.path.isfile(temp_filename): # extract failure?
sys.exit('unable to extract {} from {}'.format(PREVIEW_PATH, pages_file))
final_PDF = filename + '.pdf'
shutil.copy2(temp_filename, final_PDF) # copy and rename extracted file
# delete the temporary subdirectory created (along with pdf file in it)
shutil.rmtree(os.path.join(tempdir, os.path.split(PREVIEW_PATH)[0]))
print('Check out the PDF! It\'s located at "{}".'.format(final_PDF))
#view_file(final_PDF) # see Bonus below
else:
sys.exit('Sorry, that isn\'t a .pages file.')
Bonus: If you'd like to actually view the final pdf file from the script, you can add the following function and use it on the final pdf created (assuming you have a PDF viewer application installed on your system):
import subprocess
def view_file(filepath):
subprocess.Popen(filepath, shell=True).wait()

Categories