I am trying to create a script that moves all pictures from my downloads folder, to my pictures folder. My script works this far (moving the files over), except when it tries to move a file that already has the same name in the destination folder - like with printscreens. It will not move the file if printscreen1.png already exists in pictures.
For files like this, I would like to rename the file and add the date or time to the file name, then move it without replacing the original printscreen so I can keep both and all printscreens going toward the future.
import os
import shutil
import datetime
downloadsb = os.path.join('B:\\Downloads')
pictures = os.path.join('B:\\Pictures')
for f in os.listdir(downloadsb):
if f.endswith((".jpg", ".gif", ".jpeg", ".png", ".ico", ".psd", ".sfw", ".webp", ".pdd", ".psb", ".bmp", ".rle", ".dib", ".eps", ".iff", ".tdi", ".jpf",
".jpx", ".jp2", ".j2c", ".jxk", ".jpc", ".jps", ".mp0", ".pcx", ".pdp", ".raw", ".pxr", ".pns")):
shutil.move(os.path.join(downloadsb, f), pictures)
if os.path.isfile(f):
os.rename(f,f + "date")
Here is my error message:
raise Error, "Destination path '%s' already exists" % real_dst
shutil.Error: Destination path 'B:\Pictures\printscreen1.png' already exists
This is what I have so far, I would appreciate any help or advice. Thank you
There's a built-in library that checks to see if a file is an image. Also, you need to iterate over the files in the directory (folder). Something like this should work (not tested):
import os
import shutil
import datetime
import imghdr
downloadsb = os.path.join('B:\\Downloads')
pictures = os.path.join('B:\\Pictures')
files = os.listdir(downloadsb)
for f in files:
try:
imghdr.what(f)
dest_name = f
if os.path.exists( os.path.join(pictures, dest_name) ):
dest_name += datetime.datetime.now().strftime('%H%M%S')
shutil.move(os.path.join(downloadsb, f),
os.path.join(pictures, dest_name))
except Exception as e:
continue
Why not check it before moving. Something like below
NOTE: When the file exists you can do different types of renaming. I and just appending _new (to the extension). Not quite what you wanted but that should give an idea
import os
import shutil
import datetime
import glob
downloadsb = os.path.join('src')
pictures = os.path.join('dst')
for f in glob.glob(downloadsb + '/*'):
if f.endswith(
(".jpg", ".gif", ".jpeg", ".png", ".ico", ".psd", ".sfw", ".webp", ".pdd", ".psb", ".bmp",
".rle", ".dib", ".eps", ".iff", ".tdi", ".jpf", ".jpx", ".jp2", ".j2c", ".jxk", ".jpc", ".jps",
".mp0", ".pcx", ".pdp", ".raw", ".pxr", ".pns")):
dstFile = os.path.join(pictures, os.path.split(f)[1])
if os.path.exists(dstFile):
# Do whatever you want to rename the file here
shutil.move(f, dstFile + '_new')
else:
shutil.move(f, dstFile)
Before running
dst:
tmp.jpg
src:
tmp.jpg
After running
dst:
tmp.jpg tmp.jpg_new
src:
Related
Friends, I'm working with some folders and I'm having a hard time moving files from one folder to another. I tried to use the command shutil.move (), but I can only move one file or all that are present in the folder. I would like to move only a few files present in the folder. I thought about making a list with the name of the files, but it didn't work, could someone help me please?
follow my code:
import shutil
source = r'C:\Users1'
destiny = r'C:\Users2'
try:
os.mkdir(destiny)
except FileExistsError as e:
print (f'folder {destiny} already exists.')
for root, dirs, files in os.walk(source):
for file in files:
old_way = os.path.join(root, file)
new_way = os.path.join(destiny, file)
if ['arq1','arq2'] in file:
shutil.move(old_way, new_way)
from shutil import copyfile
import os
from os import listdir
from os.path import isfile, join
source = '/Users/xxx/path'
destiny = '/Users/xxx/newPath'
onlyfiles = [f for f in listdir(source) if isfile(join(source, f))]
for file in onlyfiles:
if ['arq1','arq2'] in file:
src = source+"/"+file
dst = destiny+"/"+file
copyfile(src,dst)
If the file is already in the new directory it will automatically replace it
I'm attempting to write a script that will save a file in the given directory, but I'm getting a NotADirecotryError[WinError 267] whenever I run it. Any ideas or tips on what I may have done incorrectly?
import shutil
import os
src = 'C:\\Users\\SpecificUsername\\Pictures\\test.txt\'
dest = 'C:\\Users\\SpecificUsername\\Desktop'
files = os.listdir(src)
for file in files:
shutil.copy(file, dest)
for file in files:
if os.path.isfile(file):
shutil.copy(file,dest) ```
There are a couple of things going on here:
You can just use forward slashes in the paths.
Your src is the test.txt file, and not a directory, so you cannot iterate over it using os.listdir().
You can also merge the two loops together since they are looping over the same set of data.
shutil.copy() takes a file path as input, while what you are passing is a filename.
The following code should work and it also copies directories as is:
import shutil
import os
basepath = "C:/Users/SpecificUsername/"
src = "Pictures/"
dest = "Desktop/"
files = os.listdir(os.path.join(basepath, src))
for filename in files:
filepath = os.path.join(basepath, src, filename)
if (os.path.isfile(filepath)):
print("File: " + filename)
shutil.copy(filepath,dest)
else:
print("Dir: " + filename)
shutil.copytree(filepath, os.path.join(dest, filename))
Hope it helps!
I tried to make a program which delete all of the empty files ( whose size is zero ). Then, i run the program by dragging the script file in "command prompt" and run it .
However, no empty files had deleted (but i have some of them).
Please help me to find the error in my code.
import os
a = os.listdir('C:\\Python27')
for folder in a :
sizes = os.stat('C:\\Python27')
b = sizes.st_size
s = folder
if b == 0 :
remove('C:\\Python27\s')
You're assigning the values iterator os.listdir returns to folder and yet you aren't using it at all in os.stat or os.remove, but instead you are passing to them fixed values that you don't need.
You should do something like this:
import os
dir = 'C:\\Python27'
for file_name in os.listdir(dir):
file_path = os.path.join(dir, file_name)
if os.stat(file_path).st_size == 0:
os.remove(file_path)
You can delete something like the following code and you need to add some exception handling. I have used a test folder name to demonstrate.
import os
import sys
dir = 'c:/temp/testfolder'
for root, dirs, files in os.walk(dir):
for file in files:
fname = os.path.join(root, file)
try:
if os.path.getsize(fname) == 0:
print("Removing file %s" %(fname))
os.remove(fname)
except:
print("error: unable to remove 0 byte file")
raise
Hi Trying to move logs that are finished being processed but I think I'm using shutil wrong.
import shutil
path = '/logs/'
finDir = '/complete/'
# parse loop
def getUniquePath(path):
for filename in os.listdir(path):
if..processing log
shutil.move(filename, finDir) #moves completed files
I keep getting errors that file does not exist.
So I added a print statement after the loop and it correctly prints out the filename and the destination so I'm thinking that I am just using shutil.move incorrectly.
Thanks
You need to combine path with filename unless you are in the /logs/ directory.
Otherwise, file searching is done in the current directory; which cause file not found, or wrong file manipulation (if there was the file with the same name in the current directory)
Using os.path.join:
import os
import shutil
path = '/logs/'
finDir = '/complete/'
# parse loop
def getUniquePath(path):
for filename in os.listdir(path):
..
shutil.move(os.path.join(path, filename), finDir)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I have a specific problem in python. Below is my folder structure.
dstfolder/slave1/slave
I want the contents of 'slave' folder to be moved to 'slave1' (parent folder). Once moved,
'slave' folder should be deleted. shutil.move seems to be not helping.
Please let me know how to do it ?
Example using the os and shutil modules:
from os.path import join
from os import listdir, rmdir
from shutil import move
root = 'dstfolder/slave1'
for filename in listdir(join(root, 'slave')):
move(join(root, 'slave', filename), join(root, filename))
rmdir(join(root, 'slave'))
I needed something a little more generic, i.e. move all the files from all the [sub]+folders into the root folder.
For example start with:
root_folder
|----test1.txt
|----1
|----test2.txt
|----2
|----test3.txt
And end up with:
root_folder
|----test1.txt
|----test2.txt
|----test3.txt
A quick recursive function does the trick:
import os, shutil, sys
def move_to_root_folder(root_path, cur_path):
for filename in os.listdir(cur_path):
if os.path.isfile(os.path.join(cur_path, filename)):
shutil.move(os.path.join(cur_path, filename), os.path.join(root_path, filename))
elif os.path.isdir(os.path.join(cur_path, filename)):
move_to_root_folder(root_path, os.path.join(cur_path, filename))
else:
sys.exit("Should never reach here.")
# remove empty folders
if cur_path != root_path:
os.rmdir(cur_path)
You will usually call it with the same argument for root_path and cur_path, e.g. move_to_root_folder(os.getcwd(),os.getcwd()) if you want to try it in the python environment.
The problem might be with the path you specified in the shutil.move function
Try this code
import os
import shutil
for r,d,f in os.walk("slave1"):
for files in f:
filepath = os.path.join(os.getcwd(),"slave1","slave", files)
destpath = os.path.join(os.getcwd(),"slave1")
shutil.copy(filepath,destpath)
shutil.rmtree(os.path.join(os.getcwd(),"slave1","slave"))
Paste it into a .py file in the dstfolder. I.e. slave1 and this file should remain side by side. and then run it. worked for me
Use this if the files have same names, new file names will have folder names joined by '_'
import shutil
import os
source = 'path to folder'
def recursive_copy(path):
for f in sorted(os.listdir(os.path.join(os.getcwd(), path))):
file = os.path.join(path, f)
if os.path.isfile(file):
temp = os.path.split(path)
f_name = '_'.join(temp)
file_name = f_name + '_' + f
shutil.move(file, file_name)
else:
recursive_copy(file)
recursive_copy(source)
Maybe you could get into the dictionary slave, and then
exec system('mv .........')
It will work won't it?