Grep command to find files containing text string and move them
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.
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.
If your file names don't contain any special characters (whitespace or \[*?
), use command substitution:
mv `grep -lir 'string' ~/directory/*` destination/