Search code examples
bashcronshexcept

Delete every week all files except some folders (but not the files into these)


I'm using this bash script to delete all files and folders located in a directory every week except three folders and the files contained into these. But how can I now modify the script so that only these three foldres remain but not the files contained? These 3 folders are necessary to a workflow but not the files contained (after 7 days).

find /Path/Folder/* -type d -mtime +7 ! -path "/Path/Folder/NODELETE1"  ! -path "/Path/Folder/NODELETE2"  ! -path "/Path/Folder/NODELETE3" -exec rm -rf {} \;

What I want is

Before

Path/NODELETE1/files
Path/NODELETE2/files
Path/NODELETE3/files
Path/FOLDERS
Path/files

After

Path/NODELETE1
Path/NODELETE2
Path/NODELETE3

EDIT:

find /path/Folder/* -and -not -path "/path/Folder/DELEGATE*" -mtime +7 ! -regextype posix-egrep ! -regex ".*/path/Folder/(DOCUMENTS|WORK|PENDING)$" -delete

Solution

  • well, first of all you don't need anymore the -type d if you want to delete files. you can use regex with find to deal with this case; a regex that matches everything that doesn't end with NODELETE[1-3]:

    find path/folder/* -regextype posix-egrep ! -regex ".*path/folder/NODELETE[1-3]$"
    

    this will match, for example:

    $ find path/folder/* -regextype posix-egrep ! -regex ".*path/folder/NODELETE[1-3]$"
    path/folder/asd
    path/folder/asd/will_delete
    path/folder/bleeegh
    path/folder/NODELETE1/eraseme
    path/folder/NODELETE2/a_folder
    path/folder/NODELETE2/a_folder/delete_me
    

    also, instead of -exec rm -rf {} you can use -delete:

    $ find path/folder/* -regextype posix-egrep ! -regex ".*path/folder/NODELETE[1-3]$" -delete
    $ tree
    .
    └── path
        └── folder
            ├── NODELETE1
            ├── NODELETE2
            └── NODELETE3
    
    5 directories, 0 files
    

    so, the folders remain, other folder and files are gone, and the files and folders inside NODELETE[1-3] are also gone.

    don't forget to add -mtime +7! (i obviated it because it's not necessary to demonstrate the case)


    if you want to keep other folders you can use an OR in the regex which won't delete the folders but will delete files inside them:

    find path/folder/* -regextype posix-egrep ! -regex ".*path/folder/(NODELETE[1-3]|DOCUMENTS|WORK|DELEGATE)$" -delete
    

    and if you want to keep the files of some folder you can specify another filter for find:

    find [...] -and -not -path "path/folder/DOCUMENTS*"
    

    notice that the * at the end will match not only the folder itself but all files inside it.