Grep command to find files containing text string and move them

I am able to locate files in a folder containing a specific text string using this command:

grep -lir 'string' ~/directory/*

How do I move the files that appear in the above result to another location?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Use xargs in concert with mv‘s third syntax: mv [OPTION]... -t DIRECTORY SOURCE...

grep -lir 'string' ~/directory/* | xargs mv -t DEST

Be careful about files containing special characters (spaces, quotes). If this is your case, filtering the list with sed (adding quotes around filenames with s/^/'/;s/$/'/) might help, but you’d have to be sure, these quotes won’t appear in the filenames. GNU grep has the -Z/--null option to NUL-terminate filenames.

An alternative to the third syntax for mv is using xargs with the placeholder string (-I).

Another option is command substitution – $( ) or backticks `` (in bash) as mentioned in ire_and_curses’ answer.

Method 2

As always, beware of grep -r. -r is not a standard option, and in some implementations like all but very recent versions of GNU grep, it follows symbolic links when descending the directory tree, which is generally not what you want and can have severe implications if for instance there’s a symlink to “/” somewhere in the directory tree.

In the Unix philosophy, you use a command to search directories for files, and another one to look at its content.

Using GNU tools, I’d do:

xargs -r0 --arg-file <(find . -type f -exec grep -lZi string {} +
  ) mv -i --target-directory /dest/dir

But even then, beware of race conditions and possible security issues if you run it as one user on a directory writeable by some other user.

Method 3

If your file names don’t contain any special characters (whitespace or [*?), use command substitution:

mv `grep -lir 'string' ~/directory/*` destination/

Method 4

Using only POSIX specified features, and making no assumptions about filenames:

find ~/directory -type f -exec grep -qiF 'string' {} ; -exec mv {} /path/to/dest ;

Notes:

You said “string” not “pattern,” so the -F (fixed string search) option of grep seems appropriate.

If your destination directory is anywhere inside of your search directory, you may have some unpleasant race conditions.

POSIX specs for grep

POSIX specs for find

Method 5

Using GNU parallel:

grep -i -Z -r -l 'string' . | parallel 'mv {} destination/{}'

ht/ @lin-dong for his original answer with xargs.

Method 6

-Assume that you have destination directory as ‘external’ and need to move all XLS files, you can try below command

sudo mv find /var/log/ -type f -name "*.xls" /external/


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x