I am using find
to locate and delete backup files but wish to exclude certain directories from the search. The backup filenames could terminate in .bck
, bak
, ~
, or backup
.
The Minimal Working Example (MWE) code with only three directories to exclude is:
#! /bin/bash
find . -type d \( -path "./.*" -o -path "./Music" -o -path "./Documents" \) -prune -o -type f \( -name "*.bck" -o -name "*.bak" -o -name "*~" -o -name "*.backup" \) -print0 | xargs -0 --no-run-if-empty trash-put
The syntax \( -path "dir1" -o -path "dir2" ... -o -path "dirN" \) -prune
seems a little clunky, especially if there are around ten directories to exclude, although I have shown only three in the MWE.
Is there a more elegant way using either an input file, with the list of excluded directories, or an array- or list-like construct, that could be pressed into service?
I am sorry for not being more explicit when I wrote my original question.
NB: trash-put
is a utility that moves the files to the Trashcan
instead of deleting them [1].
Best Answer
As far as I know, there is no option to tell
find
to read patterns from a file. An easy workaround is to save the patterns I want to exclude in a file and pass that file as input for a reversegrep
. As an example, I have created the following files and directories:If I understood the example you posted correctly, you want to move
a.bck
,.aa.bak
,b.bak
,c~
,foo.backup
anddir2/bb2.bak
to the trash and leave.aa.bak
,.dir1/bb1.bak
,Documents/Documents.bak
andMusic/Music.bak
where they are. I have, therefore, created the fileexclude.txt
with the following contents (you can add as many as you want):I use
./.*/
because I understood your original find to mean that you want to move hidden backup files (.foo
) that are in the current directory but exclude any backup files that are in hidden directories (.foo/bar
). So, I can now run thefind
command and usegrep
to exclude unwanted files:Grep options: