Bash Linux: How to move or delete files containing specific text - and 3 other useful variations

Important: All commands in this post perform bulk actions and come with no warranty. If you are operating on critical files, or are unsure about what the commands do, consider replacing mv with cp and inspecting the results. Also see the common gotchas section bellow…

The short answer

Move from /path/to/search to /path/where/to/move if body contains 'text you want to match'
find /path/to/search -type f -print0 | \
xargs -0 grep -Z -l 'text you want to match' | \
xargs -0 -I {} mv {} /path/where/to/move


  1. find /path/to/search -type f -print0

    • Prints out all file name (only files not directories!), recursing into nested folders
    • -print0 must come at the end. It uses a null instead of newline separator to prevent whitespace issues
    • This list is passed to the next xargs
  2. xargs -0 grep -Z -l 'text you want to match'

    • xargs feeds arguments from stdin into another command (grep in this case)
    • -0 makes xargs use null as separator, needed since we used -print0
    • grep

      • -Z makes grep output null separated values (like -print0)
      • -l makes grep list only the names of the matching files
    • The output of grep gets passed to the next xargs
  3. xargs -0 -I {} mv {} /path/where/to/move

    • -I {} replace {} with the list value

Useful variants

1. Matching regular expressions

find /path/to/search -type f -print0 | \
xargs -0 grep -Z -l -E 'your*regex*pattern' | \
xargs -0 -I {} mv {} /path/where/to/move

Description: Add -E if you want grep to use extended regular expressions

2. Matching only files that DO NOT include the text

find /path/to/search -type f -print0 | \
xargs -0 grep -Z -L 'text you want to match' | \
xargs -0 -I {} mv {} /path/where/to/move

Description: Note the only difference is the big -L replacing -l

3. Matching by file name instead of file content

find /path/to/search -type f -name '2021*' -print0  | \
xargs -0 -I {} mv {} /path/where/to/move

Description: Note it is important that -print0 always comes at the end of find

Common gotchas

  1. The commands above will find the files and move them into /path/where/to/move. Watchout that files with equal names will overwrite each other.

More resources