Reputation: 155
I have a bit of code that searches for files in a network share that match a certain keyword. When a match is found, I would like to copy the found files to a different location on the network. The error I'm getting is as follows:
Traceback (most recent call last):
File "C:/Users/user.name/PycharmProjects/SearchDirectory/Sub-Search.py", line 15, in <module>
shutil.copy(path+name, dest)
File "C:\Python27\lib\shutil.py", line 119, in copy
copyfile(src, dst)
File "C:\Python27\lib\shutil.py", line 82, in copyfile
with open(src, 'rb') as fsrc:
IOError: [Errno 2] No such file or directory: '//server/otheruser$/Document (user).docx'
I believe it's because I'm trying to copy the found file without specifying its direct path, since some of the files are found in subfolders. If so, how can I store the direct path to a file when it matches the keyword? Here is the code I have so far:
import os
import shutil
dest = '//dbserver/user.name$/Reports/User'
path = '//dbserver/User$/'
keyword = 'report'
print 'Starting'
for root, dirs, files in os.walk(path):
for name in files:
if keyword in name.lower():
shutil.copy(path+name, dest)
print name
print 'Done'
PS. The user folder being accessed is hidden, hence the $.
Upvotes: 1
Views: 1219
Reputation: 114230
Looking at the docs for os.walk
, your error is most likely that you are not including the full path. To avoid having to worry about things like trailing slashes and OS/specific path separators, you should also consider using os.path.join
.
Replace path+name
with os.path.join(root, name)
. The root
element is the path of the subdirectory under path
actually containing name
, which you are currently omitting from your full path.
You should also replace dest
with os.path.join(dest, os.path.relpath(root, path))
if you wish to preserve the directory structure in the destination. os.path.relpath
subtracts the path prefix of path
from root
, allowing you to create the same relative path under dest
. If the correct subfolders do not exist, you may want to call os.mkdir
or better yet os.makedirs
on them as you go:
for root, dirs, files in os.walk(path):
out = os.path.join(dest, os.path.relpath(root, path))
#os.makedirs(out) # You may end up with empty folders if you put this line here
for name in files:
if keyword in name.lower():
os.makedirs(out) # This guarantees that only folders with at least one file get created
shutil.copy(os.path.join(root, name), out)
Finally, look into shutil.copytree
, wich does something very similar to what you want. The only disadvantage is that it does not offer the fine level of control for things like filtering that os.walk
does (which you are using).
Upvotes: 3