Passing multiple directories to the -prune option in find
With GNU find (i.e. under non-embedded Linux or Cygwin), you can use -regex
to combine all these -path
wildcards into a single regex.
find . -regextype posix-extended \
-type d -regex '\./(\..*|Music|Documents)' -prune -o \
-type f -regex '.*(\.(bck|bak|backup)|~)' -print0 |
xargs -0 --no-run-if-empty trash-put
With FreeBSD or OSX, use -E
instead of -regextype posix-extended
.
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 reverse grep
. As an example, I have created the following files and directories:
$ tree -a
.
├── a
├── .aa
├── .aa.bak
├── a.bck
├── b
├── .dir1
│ └── bb1.bak
├── dir2
│ └── bb2.bak
├── b.bak
├── c
├── c~
├── Documents
│ └── Documents.bak
├── exclude.txt
├── foo.backup
└── Music
└── Music.bak
If I understood the example you posted correctly, you want to move a.bck
, .aa.bak
, b.bak
, c~
, foo.backup
and dir2/bb2.bak
to the trash and leave .aa.bak
, .dir1/bb1.bak
, Documents/Documents.bak
and Music/Music.bak
where they are. I have, therefore, created the file exclude.txt
with the following contents (you can add as many as you want):
$ cat exclude.txt
./.*/
./Music
./Documents
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 the find
command and use grep
to exclude unwanted files:
$ find . -type f | grep -vZf exclude.txt | xargs -0 --no-run-if-empty trash-put
Grep options:
-v, --invert-match
Invert the sense of matching, to select non-matching
lines. (-v is specified by POSIX.)
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. The empty
file contains zero patterns, and therefore matches
nothing. (-f is specified by POSIX.)
-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.
Group -path ... -prune
into one expression enclosed by \( ... \)
using -o
(or) logic.
find /somepath \( -path /a -prune -o \
-path /b -prune -o \
-path /c -prune \
\) \
-o -print
The example will not iterate directories or files at or under /somepath/a
, /somepath/b
, and /somepath/c
.
Here is a more specific example using multiple actions.
find / \( -path /dev -prune -o \
-path /proc -prune -o \
-path /sys -prune \
\) \
-o -printf '%p ' -exec cksum {} \;