views:

37

answers:

6

I have a directory that have a lot of files, i want to loop to each file and open it search for a specific word and then i the word found copy the file into another directory.

Thanks

+1  A: 
grep -r "term" . | sed -e 's/:.*//' | uniq | xargs -I {} cp -v {} /target/dir

.. assuming you have a grepat your hand.

The MYYN
A: 

Create a batch file like this:

FOR /F "usebackq delims==" %%i IN (`findstr /M "xxx_string_to_search_xxx" c:\source\*.*`) DO copy %%i c:\destination\

It will seach for xxx_string_to_search_xxx in C:\source and copy these files to C:\destination

DmitryK
A: 

Python

import os
import shutil
for path, dirs, files in os.walk( 'path/to/dir' ):
    for name in files:
        aFileName= os.path.join(path,name)
        with open( aFileName, "r" ) as content:
            if "myword" in content:
                shutil.copy( aFileName, "path/to/other/dir" )

This should work well enough. I haven't tested it extensively, but you can see how this would work.

S.Lott
A: 

Simple loop will take care of it for you:

for x in `grep -l <your pattern> *`
do
     cp $x <new path>/$x
done

Just incase it has spaces in the file name:

grep -l <your pattern> * | while read file
do
     cp $file <new path>/$file
done
Courtland
A: 

assuming linux and using bash shell

#!/bin/bash
dest="/destination"
shopt -s nullglob
for file in *
do
   grep "searchterm" "$file" && mv "$file" "$dest"
done
ghostdog74
A: 

Ok, if I understand you correctly, you want to:

  • Move a file to a specific directory
    • Depending on whether a certain word appears within the file or not
  • This should be done for all files in a directory

If I got that right, then it's actually very easy.

Short answer:

for %%f in (*) do (
    findstr "foo" "%%f" > NUL 2>&1
    if not errorlevel 1 copy "%%f" "some_directory"
)

Longer explanation:

First of all, iterating over a set of files (yes, "all files" is also a set of files) can be done easily with the for command:

for %%f in (*) do ...

Then you want to know whether a specific word (let's pretend it's "foo") appears in the file or not. This can be checked with the findstr command:

findstr "foo" "%%f"

Now, this will, by default, output each line where "foo" is found to the screen. And maybe even error messages, so we redirect those into nothingness:

> NUL 2>&1

findstr returns a specific numeric code, depending on whether the given string was found or not. While you usually can't see it we can still test for it. This specific code is called the error level, this heralds back to Ye Olde DOS days, or maybe even CP/M. Anyway, this error level is either 0 or 1. When it is 0 this means that the text was found, when it's 1, then the text was either not found or another error occurred.

There is a special syntax to test for the error level which has a little quirk: It tests whether the error level is at least a certain number. So for testing for 0 we need to invert it, but that doesn't matter too much:

if not errorlevel 1 copy "%%f" "some_directory"

This moves the file to some_directory, but only if the error level was not at least 1, in other words: exactly 0. Which means that the text we searched in the file has been found.

Putting it all together, this now looks like the following:

for %%f in (*) do (
    findstr "foo" "%%f" > NUL 2>&1
    if not errorlevel 1 copy "%%f" "some_directory"
)

This wasn't too hard, was it?


P.S.: We can shorten this a bit, since the batch file language has a special syntax to perform a command only when another command succeeds:

for %%f in (*) do (findstr "foo" "%%f" >NUL 2>&1 && copy "%%f" "some_directory")

We got it into a single line now. But since copy also outputs text, we can move the redirection to the end of the line to catch both the output of findstr and the output of copy:

for %%f in (*) do (findstr "foo" "%%f" && copy "%%f" "some_directory") >NUL 2>&1

And since it is a single line we don't need a batch file anymore (well, strictly speaking, we didn't need that before either) and can drop the double % to run it directly from the command line:

for %f in (*) do @(findstr "foo" "%f" && copy "%f" "some_directory") >NUL 2>&1

I included an @ before the opening parenthesis to suppress output of the commands that are run, otherwise your screen would quickly fill with the commands that were run. In a batch file you usually just include @echo off in the first line.

Joey