eugene
eugene

Reputation: 143

Move file to new directory only if it contains specified string

I have 1 folder with thousands of files and I need to loop through every single file and see if that file contains a specific string, once it has concluded that it has a specific string, it must then be moved to the correct folder. So far I have:

for filename in glob.iglob('*.txt'):
    f = open(filename)
    s = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
    if s.find('* Test Outcome : FAIL') != -1:
            src_file = os.path.join(dirSTART, filename)
            dst_file = os.path.join(dirFAIL, filename)
            shutil.move(src_file, dst_file + filename)

At the moment, it only moves the first file but I know for a fact there's more. Thanks

Upvotes: 1

Views: 3531

Answers (4)

Renae Lider
Renae Lider

Reputation: 1024

You can use the os module alone to do this.

import os
import shutil


source_dir = "this/is/source/folder"
dest_dir = "this/is/destination/folder"


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

CAUTION: Since I don't know much about your code, I am assuming all of the files are txt, that they are small and the string you are matching will always be the same.

Upvotes: 4

Padraic Cunningham
Padraic Cunningham

Reputation: 180522

Use a contextmanager and with to open your files so they will be closed each time:

from mmap import mmap, ACCESS_READ
import contextlib
from os import path
from shutil import move

for filename in glob.iglob('*.txt'):
    with open(filename) as f:
        with contextlib.closing(mmap(f.fileno(), 0, access=ACCESS_READ)) as s:
            if s.find('* Test Outcome : FAIL') != -1:
                src_file = path.join(dirSTART, filename)
                dst_file = path.join(dirFAIL, filename)
                move(src_file, dst_file)

Upvotes: 0

PYPL
PYPL

Reputation: 1859

from re import compile

pattern = compile("\* Test Outcome : FAIL")
for filename in glob.iglob('*.txt'):
    fl = open(filename, 'r')
    for i in fl.readlines():
        if pattern.search(i):
            fl.close()
            src_file = os.path.join(dirSTART, filename)
            dst_file = os.path.join(dirFAIL, filename)
            shutil.move(src_file, dst_file + filename)
            break #To stop checking other lines

Upvotes: 0

mike.k
mike.k

Reputation: 3457

Try to do f.close() after s = mmap.mmap(...)

Are you on Linux? If so, might be quicker to this in a shell command with grep and mv.

Upvotes: -1

Related Questions