The following is a solution to delete all files in a directory NOT containing a specific string.
There’s a directory containing several files. The files containing a specific keyword should be retained, while files not containing the keyword should be deleted.
First thing to use is
According to the manual, these are the relevant options to use:
-L, --files-without-match Suppress normal output; instead print the name of each input file from which no output would normally have been printed. The scanning will stop on the first match.
-R, -r, --recursive Read all files under each directory, recursively; this is equiv- alent to the -d recurse option.
-Z, --null Output a zero byte (the ASCII NUL character) instead of the character that normally follows a file name. For example, grep -lZ outputs a zero byte after each file name instead of the usual newline. This option makes the output unambiguous, even in the presence of file names containing unusual characters like newlines. This option can be used with commands like find -print0, perl -0, sort -z, and xargs -0 to process arbitrary file names, even those that contain newline characters.
To find files without the “keyword” use the command,
grep -rL "Key word or phrase" .
Search and Remove
To delete files without the “keyword” use the previous command and pipe the data as arguments to
grep -rL "Key word or phrase" . | xargs rm
A Better Search and Remove
The above method works well for standard filenames, but gives issues with filenames containing spaces, quotes, apostrophes, backslashes, or newlines. A safer way is to terminate input items with a null character so that every character is taken literally by
grep -rLZ "Key word or phrase" . | xargs -0 rm