0

New to python here. I would like to create a script that will scan my directory and if the filename contains a certain string in it, then it will automatically move to a folder of my choice. Have tried this, but to no luck:

import os
import shutil
import fnmatch
import glob

ffe_path = 'E:/FFE'
new_path = 'E:/FFE/Membership/letters'
keyword = 'membership'


os.chdir('E:/FFE/Membership')
os.mkdir('letters')



source_dir = 'E:/FFE'
dest_dir = 'E:/FFE/Membership/letters'

os.chdir(source_dir)

for top, dirs, files in os.walk(source_dir):
    for filename in files:
        if not filename.endswith('.docx'):
            continue
        file_path = os.path.join(top, filename)
        with open(file_path, 'r') as f:
            if '*membership' in f.read():
                shutil.move(file_path, os.path.join(dest_dir, filename))

Any insight would be greatly appreciated.

10 Rep
  • 2,217
  • 7
  • 19
  • 33
patriciajlim
  • 53
  • 2
  • 3
  • 9

2 Answers2

5

A simple function will do the trick:

def copyCertainFiles(source_folder, dest_folder, string_to_match, file_type=None):
    # Check all files in source_folder
    for filename in os.listdir(source_folder):
        # Move the file if the filename contains the string to match
        if file_type == None:
            if string_to_match in filename:
                shutil.move(os.path.join(source_folder, filename), dest_folder)

        # Check if the keyword and the file type both match
        elif isinstance(file_type, str):
            if string_to_match in filename and file_type in filename:
                shutil.move(os.path.join(source_folder, filename), dest_folder)

source_folder = full/relative path of source folder

dest_folder = full/relative path of destination folder (will need to be created beforehand)

string_to_match = a string basis which the files will be copied

file_type (optional) = if only a particular file type should be moved.

You can, of course make this function even better, by having arguments for ignoring case, automatically creating a destination folder if it does not exist, copying all files of a particular filetype if no keyword is specified and so on. Furthermore, you can also use regexes to match filetypes, which will be far more flexible.

agastya
  • 366
  • 1
  • 6
  • Thanks. The script moves files with exact match to the string, but does not work on filenames that are a partial match (containing the string among other words). I am getting this error. [1]: https://i.stack.imgur.com/Y8VgV.png – patriciajlim May 07 '20 at 01:12
  • Are your folder paths correct? I use linux, but I'm quite sure that Windows file paths do not have both forward and back slashes (see E:/FFE\Membership) – agastya May 07 '20 at 06:23
  • It is now only backslashes (/) – patriciajlim May 22 '20 at 17:42
1

f.read reads the file. You most likely don't want to see if the string is in a file's contents. I fixed your code to look in the file's name:

import os
import shutil
import fnmatch
import glob

ffe_path = 'E:/FFE'
new_path = 'E:/FFE/Membership/letters'
keyword = 'membership'


os.chdir('E:/FFE/Membership')
os.mkdir('letters')



source_dir = 'E:/FFE'
dest_dir = 'E:/FFE/Membership/letters'

os.chdir(source_dir)

for top, dirs, files in os.walk(source_dir):
    for filename in files:
        if not filename.endswith('.docx'):
            continue
        file_path = os.path.join(top, filename)
        if '*membership' in filename:
            shutil.move(file_path, os.path.join(dest_dir, filename))
xilpex
  • 3,097
  • 2
  • 14
  • 45