How to move and rename multiple files to a specific folder? - python

I have a small problem with a tool I built in Python.
This tool works classifying files by filenames and making folders by a word in every filename and then moving all the files to the corresponding folder.
Files:
09052019_6_filetype1_currenttime_randomnumber.xml
09052019_2_filetype2_currenttime_randomnumber.xml
09052019_9_filetype3_currenttime_randomnumber.xml
09052019_1_filetype3_currenttime_randomnumber.xml
09052019_1_filetype3_currenttime_randomnumber.xml
Actual results:
filetype1_Status_6(folder)
09052019_6_filetype1_currenttime_randomnumber.xml
filetype2_Status_2(folder)
09052019_2_filetype2_currenttime_randomnumber.xml
filetype3_Status_9(folder)
09052019_9_filetype3_currenttime_randomnumber.xml
filetype3_Status_1(folder)
09052019_1_filetype3_currenttime_randomnumber.xml
09052019_1_filetype3_currenttime_randomnumber.xml
Code Version 1.0
#!/usr/bin/python3
# v1.0
# Importing modules
import os
import shutil
import sys
# Path of input and output files
src = input('Input files: ')
dest = input('Destination files: ')
os.chdir(dest)
def classify():
for f in os.listdir(src):
splitname = f.split('_')
status = splitname[1]
topic = splitname[2]
foldername = topic + '_' + 'Status_' + status
if not os.path.exists(foldername):
os.mkdir(foldername)
shutil.move(os.path.join(src, f), foldername)
print('Sorting out files, please wait...')
classify()
print('¡DONE!')
Improvement
But in the v2.0 I would like to "improve" it a little more, just keeping the same usability but changing filenames from original name to "Message_*.xml" and it works but only moving one file, not all of them.
Current results:
filetype1_Status_6(folder)
Message_.xml
filetype2_Status_2(folder)
Message.xml
filetype3_Status_9(folder)
Message_.xml
filetype3_Status_1(folder)
Message_.xml
Expected results:
filetype1_Status_6(folder)
Message_.xml
filetype2_Status_2(folder)
Message.xml
filetype3_Status_9(folder)
Message_.xml
filetype3_Status_1(folder)
Message_.xml
Message_1.xml
Code Version 2.0
#!/usr/bin/python3
# v2.0
# Importing modules
import os
import shutil
import sys
# Path of input and output files
src = input('Input files: ')
dest = input('Destination files: ')
os.chdir(dest)
def classify():
for f in os.listdir(src):
splitname = f.split('_')
status = splitname[1]
topic = splitname[2]
foldername = topic + '_' + 'Status_' + status
newFileName = foldername + '\\' + 'Message_' + '.xml'
if not os.path.exists(foldername):
os.mkdir(foldername)
shutil.copy(os.path.join(src, f), newFileName)
print('Sorting out files, please wait...')
classify()
print('¡DONE!')

You are naming everything Message_ so you will never get multiple files. You need to parse the names in the folder and then increment the filenames accordingly.
msgName = 'Message_0'
newFileName = foldername + '\\' + msgName + '.xml'
if not os.path.exists(foldername):
os.mkdir(foldername)
else:
while os.path.isfile(newFileName) is True:
msgInt = int(msgName[8:])
msgInt += 1
msgName = msgName[:8] + str(msgInt)
newFileName = foldername + '\\' + msgName + '.xml'
shutil.copy(os.path.join(src, f), newFileName)
Now if you already have message_0.xml in your folder, you will get a message_1.xml instead, and so on.

Related

How to replace the name of several files in a folder by names on a text list

I have to change the name of several files in a folder such as:
CO201_LF.ab1
CO202_LF.ab1
CO034_LF.ab1
CO9871_LF.ab1
CO9576_LF.ab1
And replace those names with the names that I have in a list in a txt file.
How I can do that?
For the moment I have tried this without good results:
import os, fnmatch
def change_name():
file_path = '/home/SCRIPT_BIO/thesis_CSU/rbcL_LF_consolidated/ab1_RAW/'>
files_to_rename = fnmatch.filter(os.listdir(file_path), '*.ab1')
print(files_to_rename)
new_name = '/home/SCRIPT_BIO/thesis_CSU/rbcL_LF_consolidated/ab1_RAW/spp_list.txt/'>
for i, file_name in enumerate(files_to_rename):
new_file_name = new_name + str(i) + '.ab1'
os.rename(file_path + file_name,
file_path + new_file_name)
if __name__ == '__main__':
change_name()
The message that I have gotten is this:
"FileNotFoundError: [Errno 2] No such file or directory: '/home/SCRIPT_BIO/thesis_CSU/rbcL_LF_consolidated/ab1_RAW/CO201_LF.ab1' -> '/home/SCRIPT_BIO/thesis_CSU/rbcL_LF_consolidated/ab1_RAW//home/SCRIPT_BIO/thesis_CSU/rbcL_LF_consolidated/ab1_RAW/spp_list.txt0'"
What I want to get or the final product that I expect to get are those files (CO201_LF.ab1, etc.) renamed by the names in that list (spp_list.txt) in the same order.
Aegiphylla monica.ab1
Eugenia edulis.ab1
Miconia sparata.ab1
Deutemia claricia.ab1
Drapteris lineata,ab1
Maybe someone can help me?
Indent the os.rename() to be part of the "for" loop.
def change_name():
file_path = '/home/SCRIPT_BIO/thesis_CSU/rbcL_LF_consolidated/ab1_RAW/'>
files_to_rename = fnmatch.filter(os.listdir(file_path), '*.ab1')
print(files_to_rename)
new_name = '/home/SCRIPT_BIO/thesis_CSU/rbcL_LF_consolidated/ab1_RAW/spp_list.txt/'>
for i, file_name in enumerate(files_to_rename):
new_file_name = new_name + str(i) + '.ab1'
os.rename(file_path + file_name,
file_path + new_file_name)
if __name__ == '__main__':
change_name()

Python: Change file names to the names of people in a list

I have a couple slides, each slide corresponds to a person. I need to name each file (.pptx) after the individual name it references. A lot of the examples I see on mass renaming have the renaming become sequential like:
file1
file2
file3
I need:
bob.pptx
sue.pptx
jack.pptx
I was able to change names using os found on this site https://www.marsja.se/rename-files-in-python-a-guide-with-examples-using-os-rename/:
import os, fnmatch
file_path = 'C:\\Users\\Documents\\Files_To_Rename\\Many_Files\\'
files_to_rename = fnmatch.filter(os.listdir(file_path), '*.pptx')
print(files_to_rename)
new_name = 'Datafile'
for i, file_name in enumerate(files_to_rename):
new_file_name = new_name + str(i) + '.pptx'
os.rename(file_path + file_name,
file_path + new_file_name)
But again, this just names it:
Datafile1
Datafile2
etc
my example
import os from pathlib
import Path
files = os.listdir("c:\\tmp\\")
for key in range(0, len(files)):
print (files[key])
os.rename("c:\\tmp\\" + files[key], "c:\\tmp\\" + files[key].replace("-",""))
Path("c:\\tmp\\" + files[key] + '.ok').touch() # if u need add some extension
Here's how I ran your code (avoiding file paths I don't have!), getting it to print output not just rename
import os, fnmatch
file_path = '.\\'
files_to_rename = fnmatch.filter(os.listdir(file_path), '*.pptx')
print(files_to_rename)
new_name = 'Datafile'
for i, file_name in enumerate(files_to_rename):
new_file_name = new_name + str(i) + '.pptx'
print (file_path + new_file_name)
os.rename(file_path + file_name,
file_path + new_file_name)
This gave me
.\Datafile0.pptx
.\Datafile1.pptx
...
and did give me the correct sequence of pptx files in that folder.
So I suspect the problem is that you are getting the file names you want, but you can't see them in Windows. Solution: show file types in Windows. Here's one of many available links as to how: https://www.thewindowsclub.com/show-file-extensions-in-windows
Thank you everyone for your suggestions, I think I found it with a friend's help:
import os, fnmatch
import pandas as pd
file_path = 'C:\\Users\\Documents\\FolderwithFiles\\'
files_to_rename = fnmatch.filter(os.listdir(file_path), '*.pptx') #looks for any .ppt in path, can make any ext
df = pd.read_excel('Names.xlsx') #make a list of names in an xl, this won't read the header, header should be Names, then list your names)
for i, file_name in zip(df['Names'], files_to_rename): #zip instead of a nest for loop
new_file_name = i + '.pptx'
os.rename(file_path + file_name, file_path + new_file_name)
print(new_file_name)

os.rename deleting files python 3

Python novice, my simple script gets a given directory and renames all files sequentially, however it is deleting the files but the print is showing the files names getting renamed, not sure where its going wrong here.
Also, in what order does it retrieve these files?
import os
path = os.path.abspath("D:\Desktop\gp")
i = 0
for file_name in os.listdir(path):
try:
print (file_name + " - " + str(i))
os.rename(os.path.join(path,file_name), str(i))
except WindowsError:
os.remove(str(i))
os.rename(os.path.join(path,file_name), str(i))
i += 1
print(str(i) + " files.")
Edit
Below is the solution with working code, retrieves all files in a dir by creation date and assigns them a iterated number while retaining file extension.
import os
def sorted_dir(folder):
def getctime(name):
path = os.path.join(folder, name)
return os.path.getctime(path)
return sorted(os.listdir(path), key=getctime)
path = os.path.abspath("D:\Path\Here")
i = 0
for file_name in sorted_dir(path):
_, ext = os.path.splitext(file_name)
print (file_name + " - " + str(i)+ext)
os.rename(os.path.join(path,file_name), os.path.join(path, str(i) + ext))
i += 1
print(str(i-1) + " files.")
The problem is that you're using an absolute path for the source, but a relative path for the destination. So the files aren't getting deleted, they're just getting moved into the current working directory.
To fix it so they get renamed into the same directory they were already in, you can do the same thing on the destination you do on the source:
os.rename(os.path.join(path,file_name), os.path.join(path, str(i)))
From a comment, it sounds like you may want to preserve the extensions on these files. To do that:
_, ext = os.path.splitext(file_name)
os.rename(os.path.join(path,file_name), os.path.join(path, str(i) + ext))

How to check if folder has suboflders and then list the directories with listdir()?

I want to write a file searching code where I don't know if the directory I'm searching in has subdirectories and I want to check that so I don't get an error like this:
[Error 267]The directory name is invalid: 'C:/Path/To/Directory'.
I wrote a code like this where if it finds the file it breaks and stopps the program but if not it goes down a layer and so on.
filename = raw_input('> ')
path = 'C:/Path/Of/Directory/You/Want/To/Search/In'
fldr = os.listdir(path)
for f in fldr:
p = path + '/' + f
sfldr = os.listdir(p)
if os.path.exists(p + '/' + filename):
print 'Found file!!', p + '/' + filename
break
else:
for sf in sfldr:
pp = p + '/' + sf
ssfldr = os.listdir(pp)
if os.path.exists(pp + '/' + filename):
print 'Found file!!', pp + '/' + filename
break
else:
for ssf in ssfldr:
ppp = pp + '/' + ssf
sssfldr = os.listdir(ppp)
if os.path.exists(ppp + '/' + filename):
print 'Found file!!', ppp + '/' + filename
break
The easy to notice error is that when the directory doesn't have 3 layers of subfolders the program just breaks and gives an error message.So if I could check if the folder has subfolders before entering it,that would be neat.
Use os.scandir(). Provides better speed over os.walk()
Link to docs here!
Alternatively use, glob
>>> from glob import glob
>>> paths = glob('*/')
>>> paths
['bin/', 'content/', 'include/', 'lib/', 'output/']
>>>

Unzipping, renaming and migrating contents of GDB directory - Python

Currently trying to develop a catch all script that when pointed to a folder it will look through all of the subfolders and anything that is a .gdb will be moved to a new folder. Some GDBS are zipped and have a folder which then contains the GDB inside. If the GDB files have the same name once extracted, they will be appended with the suffix _2, _3, _4 and then moved to the folder with the other GDBs and won't conflict with any filenames.
Everything works except the renaming. Whereby it will rename one ok and then start placing folders inside of another gdb, before eventually failing with. WindowsError: [Error 183] Cannot create a file when that file already exists.
import shutil, errno, re, os, zipfile, os.path, sys
def unzip(source_filename, dest_dir):
with zipfile.ZipFile(source_filename) as zf:
for member in zf.infolist():
words = member.filename.split('/')
path = dest_dir
for word in words[:-1]:
drive, word = os.path.splitdrive(word)
head, word = os.path.split(word)
if word in (os.curdir, os.pardir, ''): continue
path = os.path.join(path, word)
zf.extract(member, path)
results = []
input_path = sys.argv[1]
output_path = sys.argv[2]
if input_path not in output_path:
for path, subdirs, files in os.walk(input_path):
for f in files:
if f.endswith(".zip") or f.endswith(".ZIP"):
unzip(os.path.join(path,f), path)
if input_path not in output_path:
for path, subdirs, files in os.walk(input_path):
counter = 2
for dir_name in subdirs:
if os.path.join(path, dir_name).endswith(".gdb") or os.path.join(path, dir_name).endswith(".GDB"):
if os.path.exists(output_path + "\\" + dir_name):
print "Moving " + os.path.join(path, dir_name) + " To " + output_path + "\\" + str(counter) + dir_name
os.rename(os.path.join(path, dir_name), output_path + "\\" + dir_name[:-4] + "_" + str(counter) + ".gdb")
counter + 1
else:
print "Moving " + os.path.join(path, dir_name) + " To " + output_path
shutil.move(os.path.join(path, dir_name), output_path)
else:
print "########################################"
print "########################################"
print "Please select a different output path"
print "The output path should not be contained"
print " In the input path"
print "########################################"
print "########################################"
Any help anyone could give would be greatly appreciated. Cheers!

Categories

Resources