Skip to main content
deleted 253 characters in body
Source Link
Stéphane Chazelas
  • 587.8k
  • 96
  • 1.1k
  • 1.7k

If I understand correctly, you want something like:

   If your find doesn't support -print0, you can replace it with -exec printf '%s\0' {} +.

 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 

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 in depth order) if their path contains /Caches/ not followed by /Snapshosts/.

If I understand correctly, you want something like:

  

 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 

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 in depth order) if their path contains /Caches/ not followed by /Snapshosts/.

added 215 characters in body
Source Link
Stéphane Chazelas
  • 587.8k
  • 96
  • 1.1k
  • 1.7k

If I understand correctly, you want something like:

find . -depth -print0 | perl -0lne ' if ("$_/" =~ m{/Caches(/.*)}s && $1 !~ m{/Snapshots/}) {rmdir $_ or unlink $_}' 

Before:  

 Before: After: .  .  ├── a  ├── a  │   ├── a  │   ├── a  │   └── Caches  │   └── Caches │   ├── a   │    │    └── Snapshotsa │   │   └── Snapshots └── a   │   ├── b └── Snapshots │   │    └── a    │   └── c   └── ba   │   ├── c b └── Caches  ├── a   └── b  │   │   └── foo a │    └── ac │   └── c └── b  └── a 

After:

. ├── a └── b │    ├── ac │    └── Caches │   └── ├── a │   └── Snapshots │   └── foo  │   └── a  └── b   └── ca 

If I understand correctly, you want something like:

find . -depth -print0 | perl -0lne ' if ("$_/" =~ m{/Caches(/.*)}s && $1 !~ m{/Snapshots/}) {rmdir $_ or unlink $_}' 

Before:

 . ├── a │   ├── a │   └── Caches │   ├── a   │   │   └── Snapshots │   │   └── a  │   ├── b │   │   └── a   │   └── c  └── b ├── c  └── Caches  ├── a  │   └── foo  │   └── a └── b  └── a 

After:

. ├── a │   ├── a │   └── Caches │   └── a │   └── Snapshots │   └── a └── b └── c 

If I understand correctly, you want something like:

find . -depth -print0 | perl -0lne ' if ("$_/" =~ m{/Caches(/.*)}s && $1 !~ m{/Snapshots/}) {rmdir $_ or unlink $_}' 

  

 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 
need the `s` for filenames that contain newline characters.
Source Link
Stéphane Chazelas
  • 587.8k
  • 96
  • 1.1k
  • 1.7k

If I understand correctly, you want something like:

find . -depth -print0 | perl -0lne ' if ("$_/" =~ m{/Caches(/.*)}s && $1 !~ m{/Snapshots/}) {rmdir $_ or unlink $_}' 

Before:

 . ├── a │   ├── a │   └── Caches │   ├── a │   │   └── Snapshots │   │   └── a │   ├── b │   │   └── a │   └── c └── b ├── c └── Caches ├── a │   └── foo │   └── a └── b └── a 

After:

. ├── a │   ├── a │   └── Caches │   └── a │   └── Snapshots │   └── a └── b └── c 

If I understand correctly, you want something like:

find . -depth -print0 | perl -0lne ' if ("$_/" =~ m{/Caches(/.*)} && $1 !~ m{/Snapshots/}) {rmdir $_ or unlink $_}' 

Before:

 . ├── a │   ├── a │   └── Caches │   ├── a │   │   └── Snapshots │   │   └── a │   ├── b │   │   └── a │   └── c └── b ├── c └── Caches ├── a │   └── foo │   └── a └── b └── a 

After:

. ├── a │   ├── a │   └── Caches │   └── a │   └── Snapshots │   └── a └── b └── c 

If I understand correctly, you want something like:

find . -depth -print0 | perl -0lne ' if ("$_/" =~ m{/Caches(/.*)}s && $1 !~ m{/Snapshots/}) {rmdir $_ or unlink $_}' 

Before:

 . ├── a │   ├── a │   └── Caches │   ├── a │   │   └── Snapshots │   │   └── a │   ├── b │   │   └── a │   └── c └── b ├── c └── Caches ├── a │   └── foo │   └── a └── b └── a 

After:

. ├── a │   ├── a │   └── Caches │   └── a │   └── Snapshots │   └── a └── b └── c 
added 2 characters in body
Source Link
Stéphane Chazelas
  • 587.8k
  • 96
  • 1.1k
  • 1.7k
Loading
Source Link
Stéphane Chazelas
  • 587.8k
  • 96
  • 1.1k
  • 1.7k
Loading