Error copying files - python

I'm trying to write a short Python script that will copy all files from a directory with a certain extension and place them in a different folder. Here is the script:
import os, shutil
source = "C:\\TCR_Calgary\\projects\\"
destination = "C:\\TCR_Calgary\\reference\\my_code\\city_of_calgary_scripts\\"
extension = ".py"
for root, dirs, files in os.walk(source):
for file in files:
if file.lower().endswith(extension):
shutil.copy2(file, destination)
This is the exception I get:
Traceback (most recent call last):
File "C:/TCR_Calgary/reference/my_code/city_of_calgary_scripts/python_script_copier.py", line 13, in <module>
shutil.copy2(file, destination)
File "C:\Program Files (x86)\Python26\lib\shutil.py", line 99, in copy2
copyfile(src, dst)
File "C:\Program Files (x86)\Python26\lib\shutil.py", line 47, in copyfile
raise Error, "`%s` and `%s` are the same file" % (src, dst)
shutil.Error: `AnnoMover.py` and `C:\TCR_Calgary\reference\my_code\city_of_calgary_scripts\AnnoMover.py` are the same file
I'm confused because AnnoMover.py is not in the destination folder. In my mind, the original file and its copy would be "the same" although their paths would not. There's clearly something I'm not understanding here. Any help is much appreciated!
Version: Python 2.6
Interpeter: PyCharm Community Edition 3.4
OS: Windows 7

The exception message could be a little clearer, but the last line should be shutil.copy2(os.path.join(source, file), destination) so that the source is fully qualified.

I got it to work:
import os, shutil
source = r"C:\TCR_Calgary\projects"
destination = r"C:\TCR_Calgary\reference\my_code\city_of_calgary_scripts"
extension = ".py"
for root, dirs, files in os.walk(source):
for file in files:
if file.lower().endswith(extension):
file_path = os.path.realpath(os.path.join(root, file))
shutil.copy2(file_path, destination)

Related

finding a string given a directory, extension, and string?

Currently, I'm trying to determine how to return a list of filenames in the directory containing a particular string...
here's how i began:
def searchABatch(directory, extension, searchString):
for file in os.listdir(directory):
if fnmatch.fnmatch(file, extension):
return file
print(searchABatch("procedural", ".py", "foil"))
I expected it to print simply the files with the extension ".py" in my "procedural" directory but I am getting the following error:
Traceback (most recent call last):
File "pitcher20aLP2.py", line 38, in <module>
print(searchABatch("procedural", ".py", "foil"))
File "pitcher20aLP2.py", line 34, in searchABatch
for file in os.listdir(directory):
FileNotFoundError: [Errno 2] No such file or directory: 'procedural'
You're trying to print contents of directory that doesn't exist in you current working directory. You should check if provided directory is actually a directory before calling os.listdir(), by using os.path.isdir()
def searchABatch(directory, extension, searchString):
if os.path.isdir(directory):
for file in os.listdir(directory):
if fnmatch.fnmatch(file, extension):
return file
print(searchABatch("procedural", ".py", "foil"))
Kevin is right, you are trying to find procedural in /home/2020/pitcher20a/procedural directory.
Check your working directory with os.getcwd() and change it needed by using os.chdir(path). Also, you can check if the directory is even a directory by using os.path.isdir() before using os.listdir().
Here is the python os module documentation - https://docs.python.org/2/library/os.html
Also, try to handle the errors gracefully.

why zipfile trying to unzip xlsx files?

I am trying to use the following code to unzip all the zip folders in my root folder; this code was found on this thread:
Unzip zip files in folders and subfolders with python
rootPath = u"//rootdir/myfolder" # CHOOSE ROOT FOLDER HERE
pattern = '*.zip'
for root, dirs, files in os.walk(rootPath):
for filename in fnmatch.filter(files, pattern):
print(os.path.join(root, filename))
zipfile.ZipFile(os.path.join(root, filename)).extractall(os.path.join(root, os.path.splitext(filename)[0]))
but I keep getting this error that says FileNotFoundError saying the xlsx file does not exist:
Traceback (most recent call last):
File "//rootdir/myfolder/Python code/unzip_helper.py", line 29, in <module>
zipfile.ZipFile(os.path.join(root, filename)).extractall(os.path.join(root, os.path.splitext(filename)[0]))
File "//rootdir/myfolder/Python\Python36-32\lib\zipfile.py", line 1491, in extractall
self.extract(zipinfo, path, pwd)
File "//myaccount/Local\Programs\Python\Python36-32\lib\zipfile.py", line 1479, in extract
return self._extract_member(member, path, pwd)
File "//myaccount/Local\Programs\Python\Python36-32\lib\zipfile.py", line 1542, in _extract_member
open(targetpath, "wb") as target:
FileNotFoundError: [Errno 2] No such file or directory: '\\rootdir\myfolder\._SGS Naked 3 01 WS Kappa Coated and a very long very long file name could this be a problem i dont think so.xlsx'
My question is, why would it want to unzip this excel file anyways?!
And how can I get rid of the error?
I've also tried using r instead of u for rootPath:
rootPath = r"//rootdir/myfolder"
and I get the same error.
Any help is truly appreciated!
Some filenames and directory names may have extra dots in their names, as a consequence the last line, unlike Windows filenames can have dots on Unix:
zipfile.ZipFile(os.path.join(root, filename)).extractall(os.path.join(root, os.path.splitext(filename)[0]))
this line fails. To see how that happens:
>>> filename = "my.arch.zip"
>>> root = "/my/path/to/mydir/"
>>> os.path.join(root, os.path.splitext(filename)[0])
'/my/path/to/mydir/my.arch'
With or without extra dots, problems will still take place in your code:
>>> os.path.join(root, os.path.splitext(filename)[0])
'/my/path.to/mydir/arch'
If no '/my/path.to/mydir/arch' can be found, FileNotFoundError will be raised. I suggest that you be explicit in you path, otherwise you have to ensure the existence of those directories.
ZipFile.extractall(path=None, members=None, pwd=None)
Extract all members from the archive to the current working directory. path specifies a different directory to extract to...
Unless path is an existent directory, FileNotFoundError will be raised.

Copying files into multiple directories using Python Shutil

I am trying to use shutil.copytree to copy a directory onto multiple other directories. I can't get it to work. I'm pretty sure I just need to implement ignore_errors=True, but I cant get it to work. How should I go about implementing 'ignore_errors=True' into
for CopyHere in DeleteThis:
for CopyThis in FilestoCopy:
shutil.copytree(CopyThis, CopyHere)
print('Files have been copied')
My code is as follows:
import shutil
import time
DeleteThis = ['E:', 'F:']
FilestoCopy = ['C:\\Users\\2402neha\\Desktop\\Hehe']
for Directory_to_delete in DeleteThis:
shutil.rmtree(Directory_to_delete, ignore_errors=True)
print('Directories have been wiped')
time.sleep(2)
for CopyHere in DeleteThis:
for CopyThis in FilestoCopy:
shutil.copytree(CopyThis, CopyHere)
print('Files have been copied')
Here are the error messages I get:
Traceback (most recent call last):
File "C:\Users\2402neha\OneDrive\Python\Dis Cleaner\Copy paste test.py", line 17, in <module>
shutil.copytree(CopyThis, CopyHere)
File "C:\Users\2402neha\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 309, in copytree
os.makedirs(dst)
File "C:\Users\2402neha\AppData\Local\Programs\Python\Python35\lib\os.py", line 241, in makedirs
mkdir(name, mode)
PermissionError: [WinError 5] Ingen tilgang: 'E:'
Your destination is E:
The destination directory needs to not exist.
From the documentation for shutil.copytree:
shutil.copytree(src, dst, symlinks=False, ignore=None)
Recursively copy an entire directory tree rooted at src. The destination directory, named by dst, must not already exist; it will be created as well as missing parent directories.
You probably want the directory name you're copying and to join it with the destination:
directory = os.path.basename(CopyThis)
destination = os.path.join(CopyHere, directory)
shutil.copytree(CopyThis, destination)

Create folders based on file names and copy files to them in python

I have many files in this folder structure:
test[dir]
-test1 - 123.avi
-video[dir]
-test2 - 123.avi
I want to create folders based based on file names (e.g. test1, test2) in the target dir and move files to respective folders.
I tried this based on code from another thread:
#!/usr/bin/env python
import os, shutil
src = "/home/koogee/Code/test"
dest = "/home/koogee/Downloads"
for dirpath, dirs, files in os.walk(src):
for file in files:
if not file.endswith('.part'):
Dir = file.split("-")[0]
newDir = os.path.join(dest, Dir)
if (not os.path.exists(newDir)):
os.mkdir(newDir)
shutil.move(file, newDir)
I get this error:
Traceback (most recent call last):
File "<stdin>", line 8, in <module>
File "/usr/lib/python2.7/shutil.py", line 299, in move
copy2(src, real_dst)
File "/usr/lib/python2.7/shutil.py", line 128, in copy2
copyfile(src, dst)
File "/usr/lib/python2.7/shutil.py", line 82, in copyfile
with open(src, 'rb') as fsrc:
IOError: [Errno 2] No such file or directory: 'test1'
What is weird is that there is a folder created in /home/koogee/Downloads named 'test1'
When you try to do shutil.move(), your file variable is just the file name with no context of the directory, so it is looking for a file of that name in the script's current directory.
To get an absolute path, use os.path.join(dirpath, file) as the source:
shutil.move(os.path.join(dirpath, file), newDir)

How to move all .log and .txt files to a new folder

I'm having trouble figuring out how to move all .log and .txt files in a certain folder and it's subdirectories to a new folder. I understand how to move one file with shutil. But, I tried to use a loop, unsuccessfully, to move all. Can someone help me with this? Thanks ....
import os, os.path
import re
def print_tgzLogs (arg, dir, files):
for file in files:
path = os.path.join (dir, file)
path = os.path.normcase (path)
defaultFolder = "Log_Text_Files"
if not defaultFolder.endswith(':') and not os.path.exists('c:\\Extracted\Log_Text_Files'):
os.mkdir('C:\\Extracted\\Log_Text_Files')
if re.search(r".*\.txt$", path) or re.search(r".*\.log$", path):
os.rename(path, 'C:\\Extracted\\Log_Text_Files')
print path
os.path.walk('C:\\Extracted\\storage', print_tgzLogs, 0)
Below is the trace back error:
Traceback (most recent call last):
File "C:\SQA_log\scan.py", line 20, in <module>
os.path.walk('C:\\Extracted\\storage', print_tgzLogs, 0)
File "C:\Python27\lib\ntpath.py", line 263, in walk
walk(name, func, arg)
File "C:\Python27\lib\ntpath.py", line 263, in walk
walk(name, func, arg)
File "C:\Python27\lib\ntpath.py", line 263, in walk
walk(name, func, arg)
File "C:\Python27\lib\ntpath.py", line 259, in walk
func(arg, top, names)
File "C:\SQA_log\scan.py", line 16, in print_tgzLogs
os.rename(path, 'C:\\Extracted\\Log_Text_Files')
WindowsError: [Error 183] Cannot create a file when that file already exists
According to the traceback, the log-files are already existing. The Python docs to the os.rename say:
On Windows, if dst already exists, OSError will be raised [...].
Now you can either:
delete the files manually or
delete the files automatically using os.remove(path)
If you want the files to be automatically deleted, the code would look like this (notice that I replaced your regular expression with the python endswith as suggested by utdemir):
import os, os.path
def print_tgzLogs (arg, dir, files):
for file in files:
path = os.path.join (dir, file)
path = os.path.normcase (path)
defaultFolder = "Log_Text_Files"
if not defaultFolder.endswith(':') and not os.path.exists('c:\\Extracted\Log_Text_Files'):
os.mkdir('C:\\Extracted\\Log_Text_Files')
if path.endswith(".txt") or path.endswith(".log"):
if os.path.exists('C:\\Extracted\\Log_Text_Files\\%s' % file):
os.remove('C:\\Extracted\\Log_Text_Files\\%s' % file)
os.rename(path, 'C:\\Extracted\\Log_Text_Files\\%s' % file)
print path
os.path.walk('C:\\Extracted\\storage', print_tgzLogs, 0)
It looks like are trying to use
os.rename(path, 'C:\\Extracted\\Log_Text_Files')
to move the file path into the directory C:\Extracted\Log_Text_Files, but rename doesn't work like this: it's going to try to make a new file named C:\Extracted\Log_Text_Files. You probably want something more like this:
os.rename(path, os.path.join('C:\\Extracted\\Log_Text_Files',os.path.basename(path))

Categories