How would I delete all files in a directory and its subdirectories that do not end with -out? For instance delete foo.bar but do not delete foo-out.bar.


I have tried

for a_file in $(find .  ! -name '*-out*'); do rm  $a_file; done;

But this script doesn't incorporate spaces. How would I fix that?


How about using the find command's built-in -delete action? that should be whitespace safe

find . ! -name '*-out*' -type f -delete

Otherwise, you could do a null-terminated while loop - make sure you quote the filename variable as well

while read -rd $'\0' f; do rm "$f"; done < <(find . ! -name '*-out*' -type f -print0)
| improve this answer | |

In addition to the answer.

You don't have to use a for loop. find provides -exec and -delete.

A quick test

cd `mktemp -d`
touch {1..9}\ -out{a..c}
$ find . -name '*-out*'
./2 -outb
./8 -outb
./9 -outa
./4 -outc
./6 -outb
./5 -outc
./7 -outb
./9 -outb
./2 -outa
./4 -outa
./8 -outc
./8 -outa
./7 -outc
./3 -outb
./6 -outa
./3 -outa
./1 -outb
./9 -outc
./1 -outa
./5 -outa
./4 -outb
./3 -outc
./1 -outc
./5 -outb
./2 -outc
./7 -outa
./6 -outc

It works with spaces.

What you need is:

find . ! -name '*-out*' -exec rm -f {} \;

A safer alternative: find . -name '*-out*' -exec rm -i {} \;

NOTE: use -exec rm -i {} \; to confirm deletion.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.