Write file in a new directory based on user input - python

There are lots of suggestions on how to create a directory, but I did not come across elegant solutions to saving a file in a newly created directory. The code saves files in the main folder, not id specific. I'd greatly appreciate your help. Thanks!
I'm using Windows 10 Python 3.
1) check whether "TrainData/xx-xxx" directory exists
2) if it does not exist:
create a subfolder within the "TrainData" directory and name it based on unique input (id) - this now works
save the file within this new directory (TrainData/xx-xxx) and name it xx-xxx....jpg
3) if it exists:
save the file within this new directory (TrainData/xx-xxx) and name it xx-xxx....jpg
id = input('Client ID:xx-xxx')
directory = "TrainData/" +str(id)
if not os.path.exists(directory):
os.makedirs(directory)
#with open(os.path.join(directory, '.' +str(id))) #I can't get this to work
file_name_path = directory + str(id)+ '.' +str(count)+ '.' +str(timegm(datetime.utcnow().utctimetuple())) + '.jpg'
if cv2.Laplacian(face, cv2.CV_64F).var() >200:
cv2.imwrite(file_name_path, face)
else:
count -= 1
cv2.imshow('Client', frame)
}

Its for creating a directory if not exists :
import os
directory = "TrainData/" +str(id)
if not os.path.exists(directory):
os.makedirs(directory)
Then you can open and create a file in that directory .
with open(os.path.join(directory, '.' +str(count)+ '.' +str(timegm(datetime.utcnow().utctimetuple())) + '.jpg' ), "w") as ip_file:
...

All that was missing was a '+/'. Thanks everyone!
id = input('Client ID:xx-xxx')
directory = "TrainData/" +str(id) +'/'
if not os.path.exists(directory):
os.makedirs(directory)
file_name_path = directory +"ID." +str(id)+ '.' +str(count)+ '.' +str(timegm(datetime.utcnow().utctimetuple())) + '.jpg'
if cv2.Laplacian(face, cv2.CV_64F).var() >200:
cv2.imwrite(file_name_path, face)
else:
count -= 1
cv2.imshow('Client', frame)

Related

Script on how to skip first four directories in creating folders within different subdirectories

how do I skip over the first four directories when i want to create a python script to make folders inside different directories ? Here is what I have but doesn't do anything.
import os
currentPath = r'C:\PRACT_DIRECTORY'
folders = ["Photos"]
for dir in os.walk(currentPath):
if dir == 'directories i want to skip':
continue
for dir in os.listdir(currentPath):
temp_path = currentPath + '\\' + dir
if os.path.isdir(temp_path):
for folder in folders:
if not os.path.isdir(temp_path + '\\' + dir):
photos = '2022'
newfolder = temp_path + '\\'+ folder + '\\' + photos
try:
os.makedirs(newfolder)
except OSError:
print('failed to create directories')
else:
print('successfully created directories')

Python 3.7 - How to check if file exists and rename

I am trying to figure out how to check if a file within my source folder, exists within my destination folder, then copy the file over to the destination folder.
If the file within the source folder exists within the destination folder, rename file within source folder to "_1" or _i+1 then copy it to destination folder.
For Example (will not be a .txt, just using this as an example, files will be dynamic in nature):
I want to copy file.txt from folder a over to folder b.
file.txt already exists within within folder b a. If I attempted to copy file.txt over to folder b, I would receive a copy error.
Rename file.txt to file_1.txt a. Copy file_1.txt to folder b b. If file_1.txt exists then make it file_2.txt
What I have so far is this:
for filename in files:
filename_only = os.path.basename(filename)
src = path + "\\" + filename
failed_f = pathx + "\\Failed\\" + filename
# This is where I am lost, I am not sure how to declare the i and add _i + 1 into the code.
if path.exists(file_path):
numb = 1
while True:
new_path = "{0}_{2}{1}".format(*path.splitext(file_path) + (numb,))
if path.exists(new_path):
numb += 1
shutil.copy(src, new_path)
else:
shutil.copy(src, new_path)
shutil.copy(src, file_path)
Thanks much in advance.
import os
for filename in files:
src = os.path.join(path, filename)
i = 0
while True:
base = os.path.basename(src)
name = base if i == 0 else "_{}".format(i).join(os.path.splitext(base))
dst_path = os.path.join(dst, name)
if not os.path.exists(dst_path):
shutil.copy(src, dst_path)
break
i += 1

Rename with Counter using Python

I would like to mention that pretty much all of these answers worked well to controlling what it renames, I wanted to place a check on all that worked, only one answer did not work, but if this helps anyone, they will have 3 out of 4 answers that works
My shared script works great, but it renames everything it finds in the directory so please be careful when using my shared script
for super large files I use this python
import os
# Function to rename multiple files
def main():
i = 1000
path="C:/Users/user/Desktop/My Folder/New folder/New folder/"
for filename in os.listdir(path):
my_dest ="(" + str(i) + ")" + ".txt"
my_source =path + filename
my_dest =path + my_dest
# rename() function will
# rename all the files
os.rename(my_source, my_dest)
i += 1
# Driver Code
if __name__ == '__main__':
# Calling main() function
main()
OK, so I am trying to control the counter to only see txt files, if I have .txt, .jpeg, .mpeg,
everything gets rename, how can I control this to only .txt files
One more problem, when I use this Python counter or a batch counter it flips my file names
Example
File_2019.txt - this should be renamed to (1000).txt
FileRecycled_2019.txt - this should be renamed to (1001).txt
Outcome
FileRecycled_2019.txt - this should be renamed to (1000).txt
File_2019.txt - this should be renamed to (1001).txt
When using this method based on filename it flips the order of my files
It takes it out of alphabetical order
I am working on a solution for the names being flipped once I find it I will share it so if it helps others
OK, so I have a underscore remover batch file, and that fixed the flipping
and it renames correctly
for smaller files I will use this
#echo off
Setlocal enabledelayedexpansion
Set "Pattern=_"
Set "Replace= "
For %%a in (*.txt) Do (
Set "File=%%~a"
Ren "%%a" "!File:%Pattern%=%Replace%!"
)
set count=1000
for %%f in (*.txt) do (
set /a count+=1
ren "%%f" "(!count!).txt"
)
You can accomplish this by using the pathlib module
from pathlib import Path
from os import chdir
path = Path.home() / 'desktop' / 'My Folder' / 'New folder' / 'New folder' # The path to use
to_usenum = 1000 # Start num
alltxt = list(path.glob('*.txt')) # Getting all the txt files
chdir(path) # Changing the cwd to the path
for i, txtfile in enumerate(alltxt):
to_usename = f"({to_usenum+i}).txt" # The name to use
txtfile.rename(to_usename)
The pathlib module comes in handy when it comes to files handling. The os module was used in the code to change the current working directory to the path's location because the renamed file will be placed in the current working directory.
You could check the filename has .txt before renaming.
if filename.endswith(".txt"):
os.rename(my_source, my_dest)
i += 1
On the filenames, you haven't specified an order for the names. You could use for filename in sorted(os.listdir(path)): to move through in alphabetical order.
My solution would be:
import os
import glob
def main():
path = "C:/Users/user/Desktop/My Folder/New folder/New folder/"
suffix = '.txt'
files = glob.glob(path + '*' + suffix)
for idx, filename in enumerate(sorted(files)):
os.rename(
filename,
os.path.join(path, f"({1000 + idx})" + suffix)
)
if __name__=="__main__":
main()
This uses glob to get all file paths in the folder with .txt suffix. It also uses enumerate to count each file rather than having to count the i value yourself. The file name is generated using an f-string.
I solved it an easy way:
import os
# Function to rename multiple files
def main():
i = 1000
path = 'C:/Users/user/Desktop/My Folder/New folder/New folder/'
for filename in os.listdir(path):
my_dest = f'({str(i)}).txt'
my_dest = path + my_dest
my_source = path + filename
ext = my_source.split('.')[-1]
if ext == 'txt':
os.rename(my_source, my_dest)
i += 1
# Driver Code
if __name__ == '__main__':
# Calling main() function
main()
my suggestion would be to use glob, give it a go
import os
import glob
# Function to rename multiple files
def main():
i = 1000
path="C:/Users/user/Desktop/My Folder/New folder/New folder/"
files = glob.glob(path + '*.txt')
for filename in files:
my_dest ="(" + str(i) + ")" + ".txt"
my_source =path + filename
my_dest =path + my_dest
# rename() function will
# rename all the files
os.rename(my_source, my_dest)
i += 1
# Driver Code
if __name__ == '__main__':
# Calling main() function
main()
this will search for any file name ending with txt extension

Python - Renaming all files in a directory using a loop

I have a folder with images that are currently named with timestamps. I want to rename all the images in the directory so they are named 'captured(x).jpg' where x is the image number in the directory.
I have been trying to implement different suggestions as advised on this website and other with no luck. Here is my code:
path = '/home/pi/images/'
i = 0
for filename in os.listdir(path):
os.rename(filename, 'captured'+str(i)+'.jpg'
i = i +1
I keep getting an error saying "No such file or directory" for the os.rename line.
The results returned from os.listdir() does not include the path.
path = '/home/pi/images/'
i = 0
for filename in os.listdir(path):
os.rename(os.path.join(path,filename), os.path.join(path,'captured'+str(i)+'.jpg'))
i = i +1
The method rename() takes absolute paths, You are giving it only the file names thus it can't locate the files.
Add the folder's directory in front of the filename to get the absolute path
path = 'G:/ftest'
i = 0
for filename in os.listdir(path):
os.rename(path+'/'+filename, path+'/captured'+str(i)+'.jpg')
i = i +1
Two suggestions:
Use glob. This gives you more fine grained control over filenames and dirs to iterate over.
Use enumerate instead of manual counting the iterations
Example:
import glob
import os
path = '/home/pi/images/'
for i, filename in enumerate(glob.glob(path + '*.jpg')):
os.rename(filename, os.path.join(path, 'captured' + str(i) + '.jpg'))
This will work
import glob2
import os
def rename(f_path, new_name):
filelist = glob2.glob(f_path + "*.ma")
count = 0
for file in filelist:
print("File Count : ", count)
filename = os.path.split(file)
print(filename)
new_filename = f_path + new_name + str(count + 1) + ".ma"
os.rename(f_path+filename[1], new_filename)
print(new_filename)
count = count + 1
the function takes two arguments your filepath to rename the file and your new name to the file

Python copy files to a new directory and rename if file name already exists

I've already read this thread but when I implement it into my code it only works for a few iterations.
I'm using python to iterate through a directory (lets call it move directory) to copy mainly pdf files (matching a unique ID) to another directory (base directory) to the matching folder (with the corresponding unique ID). I started using shutil.copy but if there are duplicates it overwrites the existing file.
I'd like to be able to search the corresponding folder to see if the file already exists, and iteratively name it if more than one occurs.
e.g.
copy file 1234.pdf to folder in base directory 1234.
if 1234.pdf exists to name it 1234_1.pdf,
if another pdf is copied as 1234.pdf then it would be 1234_2.pdf.
Here is my code:
import arcpy
import os
import re
import sys
import traceback
import collections
import shutil
movdir = r"C:\Scans"
basedir = r"C:\Links"
try:
#Walk through all files in the directory that contains the files to copy
for root, dirs, files in os.walk(movdir):
for filename in files:
#find the name location and name of files
path = os.path.join(root, filename)
print path
#file name and extension
ARN, extension = os.path.splitext(filename)
print ARN
#Location of the corresponding folder in the new directory
link = os.path.join(basedir,ARN)
# if the folder already exists in new directory
if os.path.exists(link):
#this is the file location in the new directory
file = os.path.join(basedir, ARN, ARN)
linkfn = os.path.join(basedir, ARN, filename)
if os.path.exists(linkfn):
i = 0
#if this file already exists in the folder
print "Path exists already"
while os.path.exists(file + "_" + str(i) + extension):
i+=1
print "Already 2x exists..."
print "Renaming"
shutil.copy(path, file + "_" + str(i) + extension)
else:
shutil.copy(path, link)
print ARN + " " + "Copied"
else:
print ARN + " " + "Not Found"
Sometimes it is just easier to start over... I apologize if there is any typo, I haven't had the time to test it thoroughly.
movdir = r"C:\Scans"
basedir = r"C:\Links"
# Walk through all files in the directory that contains the files to copy
for root, dirs, files in os.walk(movdir):
for filename in files:
# I use absolute path, case you want to move several dirs.
old_name = os.path.join( os.path.abspath(root), filename )
# Separate base from extension
base, extension = os.path.splitext(filename)
# Initial new name
new_name = os.path.join(basedir, base, filename)
# If folder basedir/base does not exist... You don't want to create it?
if not os.path.exists(os.path.join(basedir, base)):
print os.path.join(basedir,base), "not found"
continue # Next filename
elif not os.path.exists(new_name): # folder exists, file does not
shutil.copy(old_name, new_name)
else: # folder exists, file exists as well
ii = 1
while True:
new_name = os.path.join(basedir,base, base + "_" + str(ii) + extension)
if not os.path.exists(new_name):
shutil.copy(old_name, new_name)
print "Copied", old_name, "as", new_name
break
ii += 1
I always use the time-stamp - so its not possible, that the file exists already:
import os
import shutil
import datetime
now = str(datetime.datetime.now())[:19]
now = now.replace(":","_")
src_dir="C:\\Users\\Asus\\Desktop\\Versand Verwaltung\\Versand.xlsx"
dst_dir="C:\\Users\\Asus\\Desktop\\Versand Verwaltung\\Versand_"+str(now)+".xlsx"
shutil.copy(src_dir,dst_dir)
For me shutil.copy is the best:
import shutil
#make a copy of the invoice to work with
src="invoice.pdf"
dst="copied_invoice.pdf"
shutil.copy(src,dst)
You can change the path of the files as you want.
I would say you have an indentation problem, at least as you wrote it here:
while not os.path.exists(file + "_" + str(i) + extension):
i+=1
print "Already 2x exists..."
print "Renaming"
shutil.copy(path, file + "_" + str(i) + extension)
should be:
while os.path.exists(file + "_" + str(i) + extension):
i+=1
print "Already 2x exists..."
print "Renaming"
shutil.copy(path, file + "_" + str(i) + extension)
Check this out, please!
import os
import shutil
import glob
src = r"C:\Source"
dest = r"C:\Destination"
par = "*"
i=1
d = []
for file in glob.glob(os.path.join(src,par)):
f = str(file).split('\\')[-1]
for n in glob.glob(os.path.join(dest,par)):
d.append(str(n).split('\\')[-1])
if f not in d:
print("copied",f," to ",dest)
shutil.copy(file,dest)
else:
f1 = str(f).split(".")
f1 = f1[0]+"_"+str(i)+"."+f1[1]
while f1 in d:
f1 = str(f).split(".")
f1 = f1[0]+"_"+str(i)+"."+f1[1]
print("{} already exists in {}".format(f1,dest))
i =i + 1
shutil.copy(file,os.path.join(dest,f1))
print("renamed and copied ",f1 ,"to",dest)
i = 1

Categories