LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   Exclude a folder from a recursive delete? (https://www.linuxquestions.org/questions/linux-general-1/exclude-a-folder-from-a-recursive-delete-920094/)

raz230 12-22-2011 03:50 PM

Exclude a folder from a recursive delete?
 
I need to periodically delete files and folders from a directory for one of our apps.

rm -R *

won't work because I have one folder, called "app" that I need to leave alone.

I know robocopy in Windows has an exclude option, but I can't find any analogies in "rm". Is there an easy way to do this?

Snark1994 12-22-2011 04:02 PM

What about:

Code:

mv foo/bah/app foo/app_temp
rm -rf foo/bah/*
mv foo/app_temp foo/bah/app

Hope this helps,

Dark_Helmet 12-22-2011 04:19 PM

You can use the find command.

This works, but I'll be honest with you, I probably can't explain why. As such, you should try it out on an experimental directory (modeled after what you need it for):
Code:

find . -maxdepth 1 \( -path ./app -prune \) -o \( -regex "\./.*" -print \)
If that gives you a list of the top-level files and directories you want to delete, then you can delete them with this:
Code:

find . -maxdepth 1 \( -path ./app -prune \) -o \( -regex "\./.*" -print \) -exec rm -R {} \;
The reason I can't explain why is, my reading of the find command's man page, the -path, -prune, and -o options in this combination are not what I would expect to get this behavior. Then again, I could just be a moron and it's plain as day to everyone else.

Also, to be absolutely clear, the command needs to be run from the directory that contains the files to delete. If you want or need a command that isn't restricted like that, you could try:
Code:

find /path/to/dir -maxdepth 1 \( -path /path/to/dir/app -prune \) -o \( -regex "/path/to/dir/.*" -print \) -exec rm -R {} \;

Dark_Helmet 12-22-2011 04:37 PM

Another method if you're using the bash shell: the GLOBIGNORE environment variable.

For instance:
Code:

user@localhost:~/temp$ ls -ld *
drwxr-xr-x 2 user user 4096 Dec 22 16:31 app
drwxr-xr-x 2 user user 4096 Dec 22 16:31 delete_me
drwxr-xr-x 2 user user 4096 Dec 22 16:31 junk
drwxr-xr-x 2 user user 4096 Dec 22 16:31 waste_of_space
user@localhost:~/temp$ oldIGNORE=$GLOBIGNORE
user@localhost:~/temp$ export GLOBIGNORE=app
user@localhost:~/temp$ ls -ld *
drwxr-xr-x 2 user user 4096 Dec 22 16:31 delete_me
drwxr-xr-x 2 user user 4096 Dec 22 16:31 junk
drwxr-xr-x 2 user user 4096 Dec 22 16:31 waste_of_space
user@localhost:~/temp$ export GLOBIGNORE=$oldIGNORE
user@localhost:~/temp$ ls -ld *
drwxr-xr-x 2 user user 4096 Dec 22 16:31 app
drwxr-xr-x 2 user user 4096 Dec 22 16:31 delete_me
drwxr-xr-x 2 user user 4096 Dec 22 16:31 junk
drwxr-xr-x 2 user user 4096 Dec 22 16:31 waste_of_space
user@localhost:~/temp$

So, the above uses "ls -ld *" as an example whereas you would use "rm -R *" AFTER setting the GLOBIGNORE environment variable

raz230 12-22-2011 05:17 PM

@Dark_Helmut -
Thank you. I had a feeling it could be done that way, with the piped together commands. I've used that format to bulk remove files of type X older than Y. I'll experiment with that - I found my own way too. Not as elegant - but it works. I also realized that my "app" folder is a symlink so I made this:

#!/bin/bash

for file in /users/Rob/Desktop/test/*
do
if [ -d $file ]; then
echo deleting $file which is a directory
rm -Rf $file
else

if [ -L $file ]; then
echo "Ignoring $file which is a symlink" #this was the item I needed to skip over.
else
echo "deleting $file"
rm -f $file
fi
fi
done

chrism01 12-22-2011 07:11 PM

Dark_Helmet++ :)
Haven't noticed that GLOBIGNORE option before & I've never used it.
Props for a sneaky soln :)

honeybadger 12-23-2011 01:57 PM

Well another suggestion - 'chown -Rv root:root <dir>' and this will prevent the deletion of the folder if you are logged in as a different user. Another thing that can help here is the 'chattr'. I do not know the exact command the man page should help this too will prevent deletion of the directory. Guess, this should help.


All times are GMT -5. The time now is 05:28 AM.