How to move file from a folder to its sub folder? - python

I'm working with Python and have to move files from a folder to its sub-folder. I tried using shutil.move(), but it gives an error:
Cannot move a directory '%s' into itself
Here's the code:
for file in your_files:
if file in images:
shutil.move(your_folder, images_folder)
elif file in docs:
shutil.move(your_folder, docs_folder)
elif file in texts:
shutil.move(your_folder, texts_folder)
else:
shutil.move(your_folder, others_folder)
images_folder, docs_folder, texts_folder and others_folder are all sub-folders of your_folder.
How do I move files from your_folder to the corresponding sub-folders?

Everything is a file: A directory is a file. The destination directory is a file in the source folder.
You are trying to move the destination folder into it self.
You could:
Add an additional elif, to catch it and do nothing.
Ignore it.

Related

Rename and move the file to folder using shutil.move

def safe_copy(self,src,out_dir):
if not os.path.exists(out_dir):
os.makedirs(out_dir)
name = os.path.basename(src)
shutil.move(src,os.path.join(out_dir,'{}'.format(append_timestamp(name))))
safe_copy("\\\\server\\drive\\folder\\filename","\\\\server\\drive\\folder2")
I have the above function to move the file from source folder to destination folder. This function is working but the file is moving without the file extension and the file became unsupported.
Can anyone please advise me on this issue.
def safe_copy(src,out_dir):
if not os.path.exists(out_dir):
os.makedirs(out_dir)
name = os.path.basename(src)
shutil.move(src,os.path.join(out_dir,'{}'.format(append_timestamp(name)) + "." + src.split(".")[-1]))
If you are using this move method. You need to add the extension in src file.

Save file in a specific folder

I would like to save a CSV file in a specific folder, but I can't find anywhere how to do it...
this is the code
# Writing on a CSV FILE
fileToWrite = open(f"{userfinder}-{month}-{year}.csv', "a")
fileToWrite.write('Subject,Start Date,Start Time,End Date,End Time,All Day Event,Description\n')
fileToWrite.write(f'{string1}{tagesinfo2},{soup_datum},{soup_dienstbegin},{soup_datum},{soup_dienstende},,Kommentar: {soup_kommentar} Schiff: {b} Funktion: {soup_funktion} Schichtdauer: {soup_schichtdauer} Bezahlte Zeit: {soup_bezahltezeit} Mannschaft: {crew_list2}\n')
fileToWrite.close()
print(f'Datum: {soup_datum} Dienst: {string1}{tagesinfo2} --> Mannschaft: {crew_list2} --> OK')
You just have to change the working directory with os.chdir(path):
import os
path = '/Users/user/folder/example sub folder'
os.chdir(path)
#your code here
or, as mentioned in the comments, you can use:
myfolder = "c:/foo/bar/"
fileToWrite = open(f"{myfolder}/{userfinder}-{month}-{year}.csv", "a")
#in this case the path is "{myfolder}/{userfinder}-{month}-{year}"
This option includes the path when opening (only affects the one file) whereas os.chdir() changes the directory for everything (what I use personally for all of my projects, which are small).
If you don't want to change your folder for all files created and read, use the second option; but when you want a python file to affect every file in a distant location I would use os.chdir().

Save file in directory of executing file

I have a directory (data) that contains a file get_raw_data.py.
get_raw_data.py has a function to save a file.
A file present in some other directory (stock_prediction) imports this function and runs it.
The file gets saved in the stock_prediction directory.
How do I save the file in data directory?
(stock_prediction has a child directory dashboard which has the child directory data)
I could use absolute path but is there a better way?
You can create the path relatively to a file where this code is present i.e. if your file is hello.py, the __file__ will be its location:
from os.path import abspath, dirname, join
path = join(dirname(abspath(__file__)), "folder", "file.txt")
print(path)
Example:
# if run from get_raw_data.py
print(__file__) # get_raw_data.py
print(dirname(abspath(__file__))) # "data" folder
print(join(dirname(abspath(__file__)), "output.txt")) # output.txt in "data"
and based on that you can navigate anywhere if you have a permission to access/write to such location.
Also you can utilize os.makedirs(dirname(path)) to create such a location if it has folders not yet present and then write to it:
with open(path, "w"):
...

Transfering files from one directory to another via python

I'm trying to move multiple files from one directory to another.
The function I'm trying to make should move files if they begin with a value in sample_list. My issue is that there are multiple files which begins with a value in sample_list, this seems to be causing issues for shutil.
import shutil
import os
source = './train/'
dest1 = './test/'
files = [
'195_reg_6762_1540.npz',
'1369_reg_7652_-2532.npz',
'195_reg_1947_-484.npz',
'1336_reg_6209_1217.npz',
'1198_reg_3784_-934.npz',
'12_reg_3992_-10.npz',
'1369_reg_3214_-91.npz']
test_samples = [195, 1493, 409, 339, 12, 1336]
#Move files which begin with values in test_samples [edited orig post to fix typo]
for f in files:
for i in test_samples:
if (f.startswith(str(i))):
shutil.move(source+f, dest1)
Raises the error:
File "/home/usr/anaconda3/lib/python3.7/shutil.py", line 564, in move
raise Error("Destination path '%s' already exists" % real_dst)
Error: Destination path '/home/usr/Documents/project/data/test/195_reg_1947_-484.npz' already exists
It always fails if there is more than one file with a value in test samples to move.
What would be the correct way to move files which begin with values in test_samples from source directory to target directory.
This occurs when you've already successfully run the script (or parts of it once). Once the file exists in the destination directory, shutil throws an exception if you try to replace it.
See this modification that checks if the file already exists in the destination directory and, if so, deletes it and moves it back from the origin directory (note that the file must exist again in the origin directory). [Do you mean to copy instead of move?]
for f in files:
for i in test_samples:
if (f.startswith(str(i))):
if not os.path.exists(dest1+f):
shutil.move(source+f, dest1)
else:
os.remove(dest1+f)
shutil.move(source+f,dest1)

Python: folder creation when copying files

I'm trying to create a shell script that will copy files from one computer (employee's old computer) to another (employee's new computer). I have it to the point where I can copy files over, thanks to the lovely people here, but I'm running into a problem - if I'm going from, say, this directory that has 2 files:
C:\Users\specificuser\Documents\Test Folder
....to this directory...
C:\Users\specificuser\Desktop
...I see the files show up on the Desktop, but the folder those files were in (Test Folder) isn't created.
Here is the copy function I'm using:
#copy function
def dir_copy(srcpath, dstpath):
#if the destination path doesn't exist, create it
if not os.path.exists(dstpath):
os.makedir(dstpath)
#tag each file to the source path to create the file path
for file in os.listdir(srcpath):
srcfile = os.path.join(srcpath, file)
dstfile = os.path.join(dstpath, file)
#if the source file path is a directory, copy the directory
if os.path.isdir(srcfile):
dir_copy(srcfile, dstfile)
else: #if the source file path is just a file, copy the file
shutil.copyfile(srcfile, dstfile)
I know I need to create the directory on the destination, I'm just not quite sure how to do it.
Edit: I found that I had a type (os.makedir instead of os.mkdir). I tested it, and it creates directories like it's supposed to. HOWEVER I'd like it to create the directory one level up from where it's starting. For example, in Test Folder there is Sub Test Folder. It has created Sub Test Folder but won't create Test Folder because Test Folder is not part of the dstpath. Does that make sense?
You might want to look at shutil.copytree(). It performs the recursive copy functionality, including directories, that you're looking for. So, for a basic recursive copy, you could just run:
shutil.copytree(srcpath, dstpath)
However, to accomplish your goal of copying the source directory to the destination directory, creating the source directory inside of the destination directory in the process, you could use something like this:
import os
import shutil
def dir_copy(srcpath, dstdir):
dirname = os.path.basename(srcpath)
dstpath = os.path.join(dstdir, dirname)
shutil.copytree(srcpath, dstpath)
Note that your srcpath must not contain a slash at the end for this to work. Also, the result of joining the destination directory and the source directory name must not already exist, or copytree will fail.
This is a common problem with file copy... do you intend to just copy the contents of the folder or do you want the folder itself copied. Copy utilities typically have a flag for this and you can too. I use os.makedirs so that any intermediate directories are created also.
#copy function
def dir_copy(srcpath, dstpath, include_directory=False):
if include_directory:
dstpath = os.path.join(dstpath, os.path.basename(srcpath))
os.makedirs(dstpath, exist_ok=True)
#tag each file to the source path to create the file path
for file in os.listdir(srcpath):
srcfile = os.path.join(srcpath, file)
dstfile = os.path.join(dstpath, file)
#if the source file path is a directory, copy the directory
if os.path.isdir(srcfile):
dir_copy(srcfile, dstfile)
else: #if the source file path is just a file, copy the file
shutil.copyfile(srcfile, dstfile)
import shutil
import os
def dir_copy(srcpath, dstpath):
try:
shutil.copytree(srcpath, dstpath)
except shutil.Error as e:
print('Directory not copied. Error: %s' % e)
except OSError as e:
print('Directory not copied. Error: %s' % e)
dir_copy('/home/sergey/test1', '/home/sergey/test2')
I use this script to backup (copy) my working folder. It will skip large files, keep folder structure (hierarchy) and create destination folders if they don't exist.
import os
import shutil
for root, dirs, files in os.walk(the_folder_copy_from):
for name in files:
if os.path.getsize(os.path.join(root, name))<10*1024*1024:
target=os.path.join("backup", os.path.relpath(os.path.join(root, name),start=the_folder_copy_from))
print(target)
os.makedirs(os.path.dirname(target),exist_ok=True)
shutil.copy(src=os.path.join(root, name),dst=target)
print("Done")

Categories