This question already has an answer here:

It was an old problem. I knew how to delete files and exclude some, like this:

rm `find ~/temporary/Test\ 1 -mindepth 1 -maxdepth 1|grep -v 'A'`

but the problem is the folder 'Test 1' containing a space in name, the result of find was

/home/owner/temporary/Test 1/B

It makes rm error, how can I fix it?

marked as duplicate by Scott, Kevin Panko, Tog, nc4pk, Ƭᴇcʜιᴇ007 Nov 23 '13 at 16:47

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Thanks, but my most annoying problem is spaces and other special character are in the file names, those methods can't fix it. And I don't know how to search for this problem :-( – John Nov 22 '13 at 6:35
  • 1
    Don't try to parse the output of find or ls. They were not meant to have their output parsed, because find can work on files directly: mywiki.wooledge.org/ParsingLs – slhck Nov 22 '13 at 9:29
  • Okay, maybe I understood. – John Nov 22 '13 at 10:59

This solution works even with spaces but requires some typing:

find -mindepth 1 -maxdepth 1 ! -name "peter" ! -name "paul & mary" -exec rm {} \+

Or with newer find versions (findutils >= 4.2.3):

find -mindepth 1 -maxdepth 1 ! -name "peter" ! -name "paul & mary" -delete
  • 1
    The -print0 | xargs -0 version isn't needed. You can call -exec rm {} \+ directly, which would be more efficient. – slhck Nov 22 '13 at 9:30
  • @slhck Thanks, I updated my answer. Although the efficiency is questionable because xargs would lead to fewer rm calls :) – scai Nov 22 '13 at 9:41
  • Thanks scai! It works. When I saw these answers, I realized that they are simple, maybe I need to read more manuals. – John Nov 22 '13 at 10:39
  • I read it twice but somehow I managed to fail to noticed it. Whoops. – Hennes Nov 22 '13 at 12:34

Here is my take:

$ mkdir -p temp\ 1/sub\ 1
$ touch temp\ 1/{one,two,three} temp\ 1/sub\ 1/{one,two,three}
$ tree temp\ 1/
temp\ 1/
├── one
├── sub\ 1
│   ├── one
│   ├── three
│   └── two
├── three
└── two

1 directory, 6 files
$ find temp\ 1/ -maxdepth 1 -mindepth 1 -type f ! -regex '.*/.*o.*' -exec rm -v {} \;
removed ‘temp 1/three’

So the key concepts here are:

  1. The -regex filter with negation (! before option) and the pattern that is applied to the whole path of the found file.
  2. The -exec command that has the {} token replaced with properly quoted path. Remember to add the \; to mark the end of the command line.

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