I want to put proper sequence no in my file using python. Its working partially not fully. Suppose in a particular folder there is 3 files. The sequence should Num1_.doc,Num2_.pdf,Num3_.doc. It's working fine.
But suppose a new file is coming on that folder, how it maintain the proper sequence.
My code is -
import os
os.chdir('C:\\Users\\Project\\')
print(os.getcwd())
for count, f in enumerate(os.listdir()):
f_name, f_ext = os.path.splitext(f)
f_name = "Num" + str(count) + '_' + f_name
new_name = f'{f_name}{f_ext}'
os.rename(f, new_name)
Its generate Num1_.doc,Num2_.pdf,Num3_.doc etc.
Now new file is added on that folder. The sequence should Num4_.doc. How to do it in python.
Find what the maximum number is out of the current files, then rename any new files with a number 1 higher
import os
current_max = 0
for i in os.listdir():
# The number in this filename
num = int(i[3:-5])
if num > current_max:
current_max = num
# If the current_file has not been named yet
if "Num_" not in i:
#Rename by adding 1 to the current maximum number recorded
os.rename(i, f"Num_{current_max+1}")
Try to first get the maximum number already assigned from previous renamings, and then rename the remaining files starting from that number.
import os
import re
os.chdir('C:\\Users\\Project\\')
print(os.getcwd())
# find max number in filenames, if already named
filenames = [os.path.splitext(f)[0] for f in os.listdir()]
filenames = filter(lambda f: f[:3] == "Num" and len(f) >= 4, filenames)
max_n_file = max(map(lambda f: int(re.search('^[0-9]*', f[3:]).group(0)), filenames), default=0) + 1
# apply same algorithm but rename only not-"Num_" files
for _, f in enumerate(os.listdir()):
f_name, f_ext = os.path.splitext(f)
if f_name[:3] != "Num":
f_name = "Num" + str(max_n_file) + '_' + f_name
new_name = f'{f_name}{f_ext}'
os.rename(f, new_name)
max_n_file += 1
Related
I am reading in all the files in a given folder:
import os
path = '/Users/user/Desktop/folder_name'
files = os.listdir(path)
I have multiple files (100+) with the following names:
20220330_a.txt 20220330_b.txt 20220330_c.txt
I want to replace the "20220331" to "20220630" in the actual file names in the folder, so I obtain 20220630_a.txt, 20220630_b.txt etc.
Any ideas?
I figured it out myself:
old_date = "20200331"
new_date = "20200630"
for file in os.listdir(path):
if file.startswith(old_date):
if file.find(old_date) > -1:
counter = counter + 1
os.rename(os.path.join(path, file), os.path.join(path, file.replace(old_date,new_date)))
if counter == 0:
print("No file has been found")
I have some files as below:
As a result, I want to have:
49111809953_1.txt
78100705693_1.txt
78100705693_2.txt
78100705693_3.txt
but now I have:
49111809953_1.txt
78100705693_**2**.txt
78100705693_3.txt
78100705693_4.txt
Anyone have any idea where I should add something to start counting over if the filename is different?
import os
import re
folderPath = r'C:/Users/a/Desktop/file'
fileSequence = 1
if os.path.exists(folderPath):
files = []
for name in os.listdir(folderPath):
if os.path.isfile(os.path.join(folderPath, name)):
files.append(os.path.join(folderPath, name))
print(files)
for ii in files:
os.rename(ii, folderPath + '/' + str(os.path.basename(ii).split("ODS")[0]) + str(fileSequence) + '.txt')
fileSequence += 1
Suppose the following unordered list:
# After os.listdir()
files = ['C:/Users/a/Desktop/file/78100705693_ODS_2_231711.txt',
'C:/Users/a/Desktop/file/49111809953_ODS_2_231648.txt',
'C:/Users/a/Desktop/file/78100705693_ODS_2_231655.txt',
'C:/Users/a/Desktop/file/78100705693_ODS_2_231702.txt']
You can use groupby from itertools and pathlib:
from itertools import groupby
import pathlib
for name, grp in groupby(sorted(files)):
for seq, file in enumerate(grp, 1):
file = pathlib.Path(file)
new_name = f"{file.stem.split('_', maxsplit=1)[0]}_{seq}"
file.rename(file.with_stem(new_name))
You need to reset your variable fileSequence each time the first part of the file name changes.
This is what I would do, based on your code:
import os
import re
folderPath = r'C:/Users/a/Desktop/file'
if os.path.exists(folderPath):
files = []
for name in os.listdir(folderPath):
if os.path.isfile(os.path.join(folderPath, name)):
files.append(os.path.join(folderPath, name))
prefix = None
for this_file in files:
current = os.path.basename(this_file).split("ODS")[0]
if prefix is None or current != prefix:
prefix = current
fileSequence = 1
os.rename(this_file, folderPath + '/' + prefix + str(fileSequence) + '.txt')
fileSequence += 1
I'm using this Python code in Windows:
shutil.move(documents_dir + "\\" + file_name, documents_dir + "\\backup\\"
+ subdir_name + "\\" + file_name)
When this code is called more times, it overwrites the destination file. I would like to move the file
and if the destination already exists, to rename it
e.g. file_name = foo.pdf
and in backup folder will be foo.pdf, foo(1).pdf, foo(2).pdf etc. or similarly e.g. with dashes
foo-1.pdf, foo-2.pdf etc.
You could just check with os.path.exists() as you're going.
import os
import shutil
file_name = 'test.csv'
documents_dir = r'C:\BR\Test'
subdir_name = 'test'
# using os.path.join() makes your code easier to port to another OS
source = os.path.join(documents_dir, file_name)
dest = os.path.join(documents_dir, 'backup', subdir_name, file_name)
num = 0
# loop until we find a file that doesn't exist
while os.path.exists(dest):
num += 1
# use rfind to find your file extension if there is one
period = file_name.rfind('.')
# this ensures that it will work with files without extensions
if period == -1:
period = len(file_name)
# create our new destination
# we could extract the number and increment it
# but this allows us to fill in the gaps if there are any
# it has the added benefit of avoiding errors
# in file names like this "test(sometext).pdf"
new_file = f'{file_name[:period]}({num}){file_name[period:]}'
dest = os.path.join(documents_dir, 'backup', subdir_name, new_file)
shutil.move(source, dest)
Or since this is probably used in a loop you could just drop it into a function.
import os
import shutil
def get_next_file(file_name, dest_dir):
dest = os.path.join(dest_dir, file_name)
num = 0
while os.path.exists(dest):
num += 1
period = file_name.rfind('.')
if period == -1:
period = len(file_name)
new_file = f'{file_name[:period]}({num}){file_name[period:]}'
dest = os.path.join(dest_dir, new_file)
return dest
file_name = 'test.csv'
documents_dir = r'C:\BR\Test'
subdir_name = 'test'
source = os.path.join(documents_dir, file_name)
dest = get_next_file(file_name, os.path.join(documents_dir, 'backup', subdir_name))
shutil.move(source, dest)
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
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