I'm writing a script to automate the creation of a test file/folder structure - input for another script (to move only some files according to a file list). My code below works, but is there a more pythonic way to complete the same task?
import os
import shutil
os.chdir('c:/')
if not os.path.exists('c:/pythontest'):
os.mkdir('c:/pythontest')
else:
shutil.rmtree('c:/pythontest')
os.mkdir('c:\pythontest')
os.chdir('c:/pythontest')
for i in range(0,3):
os.mkdir('folder%d' % i)
fileName = 'folder%d' % i
filePath = os.path.join(os.curdir, fileName)
print filePath
os.chdir(filePath)
for j in range(0,3):
os.mkdir('folder%d_%d' % (i,j))
fileName = 'folder%d_%d' % (i,j)
filePath = os.path.join(os.curdir, fileName)
print str(filePath)
os.chdir(filePath)
for k in range(0,3):
try:
f = open('file%d_%d_%d.txt' % (i,j,k), 'w')
except IOError:
pass
os.chdir('..')
os.chdir('..')
I can only suggest several minor style improvements -- and moving everything within a function, which speeds things up. E.g:
import os
import shutil
def doit():
shutil.rmtree('c:/pythontest', ignore_errors=True)
os.mkdir('c:/pythontest')
os.chdir('c:/pythontest')
for i in range(0,3):
fileName = 'folder%d' % i
print fileName
os.mkdir(fileName)
os.chdir(fileName)
for j in range(0,3):
fileName = 'folder%d_%d' % (i,j)
print fileName
os.mkdir(fileName)
os.chdir(fileName)
for k in range(0,3):
try:
with open('file%d_%d_%d.txt' % (i,j,k), 'w'):
pass
except IOError:
pass
os.chdir('..')
os.chdir('..')
The minor but cumulative improvements include avoidance of repetition, and avoidance of redundancy (such as prepending a './' to filenames to make exactly equivalent filepaths).
Related
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)
Looking to make the following code recurse through sub-folders.
It works as I want it to right now, but I'm having difficulty wrapping my head around recursing through subfolders with the same for/if statements I already have in place. More of a logic block, thanks in advance.
import os
import sys
from datetime import datetime
from pathlib import Path
#search through entire path given as parameter, recursive
runtimepath = sys.argv
currenttime = "output" + (str(datetime.now().strftime("%m-%d-%Y-%H%M") + ".txt"))
print ("File", currenttime, "being generated.")
output_file = open(os.path.join(runtimepath[1], currenttime), "w")
ext_list = [
"txt","webm","mkv","flv","vob","ogv","ogg","drc","gif","gifv","mng",
"avi","mts","m2ts","mov","qt","wmv","yuv","rm","rmvb","asf","amv","mp4","m4p","m4v",
"mpg","mp2","mpeg","mpe","mpv","m2v","svi","3gp","3g2","mxf","roq","nsv","flv","f4v",
"f4p","f4a","f4b","mp3"
]
for f in os.listdir(runtimepath[1]) :
for extension in ext_list:
if f.endswith(extension) == True :
#print(f)
temp_string = os.path.join(runtimepath[1],f)
print (temp_string)
output_file.write(temp_string)
output_file.write("\n")
output_file.close();
Thanks. The below served my needs:
for root, dirs, files in os.walk(runtimepath[1]):
for file in files:
for extension in ext_list:
if file.endswith(extension) == True:
print(file)
temp_string = os.path.join(runtimepath[1],file)
print (temp_string)
output_file.write(temp_string)
output_file.write("\n")
I have a range of folders which are named like folder0, folder2,..., folder99. Now I want to walk through folder0,..., folderX and print their files. X should stay variable and easy to change.
My code looks something like this but its not working how I want it to work yet because I can't decide until which number I want to go.
import os
import re
rootdir = r'path'
for root, dirs, files in os.walk(rootdir):
for dir in dirs:
if not re.match(r'folder[0-9]+$', dir):
dirs.remove(dir)
for file in files:
print files
Assuming your name scheme is consistent, which you state, why do the os.walk?
import os
dir_path = '/path/to/folders/folder{}'
x = 10
for i in range(0, x):
formatted_path = dir_path.format(i)
try:
for f in os.listdir(formatted_path):
filename = os.path.join(formatted_path, f)
if os.path.isfile(filename):
print filename
except OSError:
print "{} does not exist".format(formatted_path)
Trying to resolve the issue But no luck yet. Can some body tell me what's the issue. Tried re indenting the code.
I am not able to print the File Not found text in the exception block in the code.
Is this the indentation issue ?
Code Snippet:
from xlutils.copy import copy
from xlrd import open_workbook
import xlwt
import os
import shutil
import glob
def openexcel_main():
book = open_workbook('input.xls',formatting_info=True)
sheet = book.sheet_by_index(0)
wb = copy(book)
w_sheet = wb.get_sheet(0)
folder_name=['do_not_delete','internal_builds']
for j in range (0,2):
folder=folder_name.pop()
for i in range (1,(sheet.nrows)):
cell_test_group = sheet.cell(i,0)
data=str(cell_test_group.value)
print '#####################################'
print data
list=[]
source_path='/mnt/'+folder+'/pybuild/'+data+'/MAIN/'
if os.path.exists(source_path):
try:
os.chdir(source_path)
all_subdirs = [d for d in os.listdir('.') if os.path.isdir(d)]
for dirs in all_subdirs:
dir = os.path.join('/mnt/'+folder+'/pybuild/'+data+'/MAIN/', dirs)
os.chdir(dir)
current = os.getcwd()
new = str(current).split("/")[6]
list.append(new)
list.sort()
val=list
for i in range (1,4):
if val==[]:
break
else:
print i
current_build_number=val.pop()
print 'Current_Build:'+current_build_number
source_path_copy = r""+ source_path+"/"+current_build_number+"/"
print 'Copying From:'+ source_path_copy
dest_path = r"/home/builds_repo/"+folder+"/pybuild/"+data+"/MAIN/"+current_build_number+"/"
os.chdir(source_path_copy)
file_name=(glob.glob('*[_bin].*')).pop()
print 'File_Copied:'+ file_name
if not os.path.exists(dest_path):
os.makedirs(dest_path)
shutil.copyfile(source_path_copy + file_name, dest_path + file_name)
except:
print'File Not Found ..'
raise
def main():
openexcel_main()
main()
Try some good editors like pyscripter ,Emacs to make your pythonic life easy :)
I have tried to intend your code ...
from xlutils.copy import copy
from xlrd import open_workbook
import xlwt
import os
import shutil
import glob
def openexcel_main():
book = open_workbook('input.xls',formatting_info=True)
sheet = book.sheet_by_index(0)
wb = copy(book)
w_sheet = wb.get_sheet(0)
folder_name=['do_not_delete','internal_builds']
for j in range (0,2):
folder=folder_name.pop()
for i in range (1,(sheet.nrows)):
cell_test_group = sheet.cell(i,0)
data=str(cell_test_group.value)
print '#####################################'
print data
list=[]
source_path='/mnt/'+folder+'/pybuild/'+data+'/MAIN/'
if os.path.exists(source_path):
try:
os.chdir(source_path)
all_subdirs = [d for d in os.listdir('.') if os.path.isdir(d)]
for dirs in all_subdirs:
dir = os.path.join('/mnt/'+folder+'/pybuild/'+data+'/MAIN/', dirs)
os.chdir(dir)
current = os.getcwd()
new = str(current).split("/")[6]
list.append(new)
list.sort()
val=list
for i in range (1,4):
if val==[]:
break
else:
print i
current_build_number=val.pop()
print 'Current_Build:'+current_build_number
source_path_copy = r""+ source_path+"/"+current_build_number+"/"
print 'Copying From:'+ source_path_copy
dest_path = r"/home/builds_repo/"+folder+"/pybuild/"+data+"/MAIN/"+current_build_number+"/"
os.chdir(source_path_copy)
file_name=(glob.glob('*[_bin].*')).pop()
print 'File_Copied:'+ file_name
if not os.path.exists(dest_path):
os.makedirs(dest_path)
shutil.copyfile(source_path_copy + file_name, dest_path + file_name)
except Exception ,e: #Use Exception if not sure which exception will raise
print'File Not Found ..',e
#raise
def main():
openexcel_main()
if __name__ == '__main__': #Use main
main()
Line:
print'File Not Found ..'
, should be in else loop of
os.path.exists(source_path):
to check and print source path is not exists
Im making a small python program to copy some files. My filenames are in a list "selectedList".
The user has selected the source dir "self.DirFilename" and the destination dir "self.DirDest".
I'm using cp instead of shutil because I've read that shutil is slow.
Heres my code:
for i in selectedList:
src_dir = self.DirFilename + "/" + str(i) + ".mov"
dst_dir = self.DirDest
r = os.system('cp -fr %s %s' % (src_dir, dst_dir))
if r != 0:
print 'An error occurred!'**
I would like the copy to search the source directory for the given filename and then recreate the folder structure in the destination as well as copy the file.
Any suggestions would be helpful (like any massively obvious mistakes that i'm making)- its my first python programme and I'm nearly there!
Thanks
Gavin
I think something like this could do the trick. Of course you may want to use something ore advance that os.system to call cp.
import os
for r, d, f in os.walk(self.DirFilename):
for file in f:
f_name, f_ext = os.path.splitext(file)
if ".mov" == f_ext:
if f_name in selectedList:
src_abs_path = os.path.join(r, file)
src_relative_path = os.path.relpath(src_abs_path, self.DirFilename)
dst_abs_path = os.path.join(self.DirDest, src_relative_path)
dst_dir = os.path.dirname(dst_abs_path)
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
ret = os.system('cp -fr %s %s' % (src_abs_path, dst_abs_path))
if ret != 0:
print 'An error occurred!'
See http://blogs.blumetech.com/blumetechs-tech-blog/2011/05/faster-python-file-copy.html for a pure Python implementation of the recursive copy.
You can use os.walk to find the file you need:
def find_files(...):
for ... in os.walk(...):
if ...:
yield filename
for name in find_files(...):
copy(name, ...)
import glob
for fname in selectedList:
filename = str(fname) + '.mov'
found = glob.glob(os.path.join(self.DirFilename, filename))
found.extend(glob.glob(os.path.join(self.DirFilename, '**', filename)))
found = [(p, os.path.join(self.DirDest, os.path.relpath(p, self.DirFilename))) for p in found]
for found_file in found:
# copy files however
#r = os.system('cp -fr %s %s' % found_file)