Bash help needed

Forum: LinuxTotal Replies: 5
Author Content
Sander_Marechal

Oct 31, 2008
9:00 AM EDT
Hi all,

I need some help with bash. I want to make a list of all empty directories under a certain directory (recursively) so I can remove them all from Subversion (svn del). Two things make this difficult:

1) The empty directories are not really empty. They still contain a .svn hidden subdirectory.

2) It needs to work recusive.

Example, given the following directory tree:

foo     .svn     bar         .svn         bar.txt     baz         .svn         quu             .svn             quux                 .svn

When it runs on foo it should return "baz" and everything under it.

Any ideas? I can't figure it out. `find` does allow me to exclude stuff (like .svn directories), but the -empty switch still isn't triggered.
Sander_Marechal

Oct 31, 2008
9:28 AM EDT
Found something:

for i in `find . -type d -print -name ".svn" | grep -v "/.svn"` do if [ -z "`ls -A $i | grep -v '.svn' `" ] then echo Removing $i ls -A $i svn remove $i fi done
gus3

Oct 31, 2008
12:00 PM EDT
Advice: Before turning loose a script like that, don't actually do irreversible commands. Especially, put "echo" in front of any commands that remove files.

Also, quoting the parameter to "-name" in the find command is necessary only when wildcard matching may cause the parameter to expand into more than one name. To prevent this, use single quotes, not double.
hkwint

Nov 01, 2008
5:28 PM EDT
That script doesn't make much sense to me. Everything in find after -print is neglected.

Here's an example to show it's neglected:

$find . -type d -print ! -type d

If the part after print is not neglected, it should not find anything because it should return files which are and are not a directory. Logically, that can never be the case. Nonetheless, it still returns all directories. -print is not needed anyway, as it is the default as far as I know. The reverse grep can be inlined in the find function. Therefore, you could simplify the find function to:

find . -type d ! -name ".svn"

and AFAIK have the same results. I made your example directory tree and it WORKSFORME.

Also, as far as I can see, this script is not going to work, because 'find' first finds the top directory 'baz' which isn't (empty except .svn) at that moment because it contains other dirs. Therefore the [ ] (test) is not going to return -z (the zero-string) on this directory, and it will not be deleted by SVN. Or am I wrong? To fix this, you need finds -depth option.

Also, I'm not a huge fan of the backticks. They cannot be nested and make the script unclear. So I'd rather see:

for i in $(find . -depth -type d ! -name ".svn") do   if [ -z "$( ls -A $i | grep -v '.svn' ) " ]   then     echo Removing $i     ls -A $i         svn remove $i   fi done

But that's just my limited bash-skill, I don't have any idea if this will work.
hkwint

Nov 01, 2008
5:29 PM EDT
ED: That's twice. ED2: Script doesn't work, because the dirs that are empty except for .svn dirs are not deleted, and therefore the parent dirs are not empty. Need another script I think?
Sander_Marechal

Nov 02, 2008
5:13 PM EDT
@hans: `svn remove` can deal with those non-empty directories, so thanks for the script!

You cannot post until you login.