I'm having the following problem. I have a directory structure and want to delete everything that is within a directory named Caches
. Everything should be delete except all directories named Snapshots
. I can't figure out how to do this with find or any other command I know.
The reason I'm asking: On iOS every app has its own Caches directory. These sometimes don't get cleared properly, depending on the app. With the solution to this answer, one would be able to clear Caches on iOS, and therefore optimize the disk space, when the devices' drive is mounted on another computer, e.g. with FUSE (iExplorer).
This is what I have so far:
find . 2>/dev/null -type d -name "Caches" -maxdepth 3 -print
This returns something like:
./Library/Caches
When I do a ls ./Library/Caches
I see all contents and the Snapshots
directory, which I want to exclude because ultimately I want to -delete
everything except this one.
I want something like this:
Before: After:
. .
├── a ├── a
│ ├── a │ ├── a
│ └── Caches │ └── Caches
│ ├── a │ └── a
│ │ └── Snapshots │ └── Snapshots
│ │ └── a │ └── a
│ ├── b └── b
│ │ └── a └── c
│ └── c
└── b
├── c
└── Caches
├── a
│ └── foo
│ └── a
└── b
└── a
Best Answer
If your
find
doesn't support-print0
, you can replace it with-exec printf '%s\0' {} +
.The idea is to print the list of files NUL-terminated (as 0 is the only byte that can't occur in a file path) and use
perl
's-n
with-0
option to run some code for each of those filenames (with$_
set to the filename).With
-depth
, files are printed before their parent directory. We remove only files or directories (assuming they are empty which is why it's important to process the list indepth
order) if their path contains/Caches/
not followed by/Snapshosts/
.