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
Related
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
I have a folder which has files with names:
"fileX.JPG" where X = 1....N
and I want to name the files as :
"000000000X.JPG" where X=1...N
The new name of the file should have the number from the old name of the file plus the zeros. so example file names I want is:
0000000000001.jpg
0000000000011.jpg
0000000000111.jpg
etc
The file name is 13 characters long. so should have zeros accordingly.
I have not started my code. Don't know where should I start.
You can use os.rename() from the os module
for path in pathlib.Path("a_directory").iterdir():
if path.is_file():
old_name = path.stem
#original filename
old_extension = path.suffix
#original file extension
Also try this:
import os
path = '/Users/myName/Desktop/directory'
files = os.listdir(path)
for index, file in enumerate(files):
os.rename(os.path.join(path, file), os.path.join(path, ''.join([str(index), '.jpg'])))
directory = path.parent
#current file location
new_name = "text" + old_name + old_extension
path.rename(pathlib.Path(directory, new_name))
You can use os.rename.
For example:
for file in os.listdir():
# Get the number, e.g.:
old_number = file.strip("file")[1].strip(".JPG")[0]
os.rename(file, f"{old_number}.JPG")
You might have to adapt based on how your files are actually namd
import os
# Function to rename multiple files
def main():
for count, filename in enumerate(os.listdir("path-to-files")):
d = str(count).zfill(12)
dst = d + ".jpg"
src ='path-to-file'+ filename
dst ='path-to-file'+ dst
# rename() function will
# rename all the files
os.rename(src, dst)
# Driver Code
if __name__ == '__main__':
# Calling main() function
main()
I'd like to rename a list of video cuts in a folder (in my case /Desktop/Cuts/)
from:
xxx.mp4, yyy.mp4, ..., zzz.mp4
to:
1.mp4, 2.mp4, ..., 33.mp4.
1.mp4 will be the video that was first created in the folder. 2.mp4 will be the second, etc.
What I am doing now (please see code below) renames the video cuts in /Cuts/, but according to an order that I don't understand, and that is definitely NOT creation date. (it does not seem alphabetical, either)
import os
path = '/Users/ntelmaut/Desktop/Cuts/'
i = 1
for file in os.listdir(path):
new_file_name = "{}.mp4".format(i)
os.rename(path + file, path + new_file_name)
#print path + file
i = i+1
I have tried make a variable out of os.listdir(path) and to apply sorted() function, but to no avail yet (I am a newbie to Python - sorry).
Would love a pointer, here.
Thank you!
Solution
import glob
import os
dirpath = '/Users/ntelmaut/Desktop/Cuts/'
files = glob.glob(os.path.join(path, '*.mp4'))
files.sort(key=os.path.getmtime)
for i, filename in enumerate(files, 1):
try:
os.rename(filename, "{0}.mp4".format(i))
except OSError as e:
print("OSError: ", e)
If I understand correctly this is what you want.
import os
path = '/Users/ntelmaut/Desktop/Cuts/'
def sort_key(file):
return os.stat(file).st_ctime
files = os.listdir(path)
sorted_files = sorted((os.path.join(path, f) for f in files), key=sort_key)
i = 1
for file in sorted_files:
new_file_name = f"{i}.mp4"
os.rename(file, new_file_name)
i += 1
A cleaner way would be to use the pathlib module.
from pathlib import Path
p = Path('/Users/ntelmaut/Desktop/Cuts/')
def sort_key(path):
return path.stat().st_ctime
sorted_files = sorted(p.iterdir(), key=sort_key)
for idx, file in enumerate(sorted_files, 1):
new_name = f"{idx}.mp4"
file.rename(p / new_name)
I want to rename images that were previously copied from multiple subfolders to the name of the subfolder from which the image came. With my actual code I can only rename images, when I enter the actual file name. But this name always varies.
For example:
C:/sub/folder/1/
rename these images from this folder to 1.jpg
My actual code:
paths = (os.path.join(root, filename)
for root, _, filenames in os.walk(dir_dst):
for filename in filenames:
for path in paths:
newname= path.replace('image_name','new_image_name')
if newname != path:
os.rename(path, newname)
I hope you understand what I mean.
Have you tried something like this
x = os.path.abspath('file_to_rename')
x = os.path.dirname(x)
x = os.path.basename(x)
That will set the name of the current folder to x. From there you could design some incrementing loop with i and rename your files to
os.rename('file_to_rename', x + '_' + str(i))
and then just increase i += 1
I've found the solution:
import os, shutil
src_g = os.getcwd()
dst_g0 = src_g.split('\\')
dst_g0.pop()
dst_g = '\\'.join(dst_g0)+'\\DestinationFolder\\'
for i in os.listdir(src_g):
if os.path.isdir(i):
name = i
neuer_pfad = src_g+'\\'+name+'\\folder_with_images\\'
for j in os.listdir(neuer_pfad):
neue_datei = neuer_pfad+j
if os.path.isfile(neue_datei):
shutil.copyfile(neue_datei, dst_g+name+'_'+j)
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