6
I'm trying to delete all empty folders within a directory. However, find . -type f -empty
does not find anything because every folder contains a hidden .svn
folder.
How can I work around this?
6
I'm trying to delete all empty folders within a directory. However, find . -type f -empty
does not find anything because every folder contains a hidden .svn
folder.
How can I work around this?
1
If you can, you can off course first remove all .svn
folders. Downside: you'll lose version control information, if someone is using SVN. If someone is using SVN, then it's not good idea to just remove those folders (or actually you have to remove those from SVN too, as SVN is tracking folders and files).
If that's not possible, I would go with scripting route:
for folder in $(find . -type d); do
if [ "`ls $folder | wc -l`" -eq 0 ]; then
echo "I am going to delete $folder"
fi
done
First try test-run, because there might be something surprising. Then you can change rm -r
instead of that echo
.
Note however, this will remove all folders with only dot-files (so for example a/.this_is_super_important
will be deleted, if there is no other files or folders).
3
Minor modification (simply print the directory and pipe into xargs
later):
for folder in $(find -type d ! -path *.svn*); do
if [ "`find $folder ! -path *.svn* ! -path $folder | wc -l`" -eq 0 ]; then
echo $folder
fi
done
Put this somewhere in your $PATH
, maybe as svn-empties
and then first run:
svn-empties
to list which directories it found (modify list if necessary) and then pipe into xargs
:
svn-empties | xargs svn rm
This script has become very useful to me while using git-svn
(thank you!). Since git
does not track empty directories I can end up with many empty directories in the Subversion repository. I svn co
a separate copy of the repository and run svn-empties | xargs svn rm
periodically. Using Subversion in the first place was not my decision ;)
If you are using git-svn
you may want to use the --rmdir
option of git svn dcommit
. It will take care of removing directories from svn as soon as they are empty. – gioele – 2015-09-11T08:36:19.257
2
I just stumbled upon this and I used this script but modified it to properly consider empty dirs only the ones with .svn and no other file, hidden or normal.
Also, bear in mind that I am using svn rm, so this is suppose to work against a repository, you could adapt the script to do something different on the directory.
for folder in $(find -type d ! -path *.svn*); do
if [ "`find $folder ! -path *.svn* ! -path $folder | wc -l`" -eq 0 ]; then
svn rm $folder
fi
done
0
svn-empties YOU_WANT_TO_SEARCH_PATH
C_IFS=$IFS
IFS=$'\n'
for folder in $(find "$1" -depth -type d ! -path *.svn*|sort -r); do
counts=$(find "$folder" -type f ! -path *.svn* ! -path $folder | wc -l)
if [ $counts -eq 0 ]; then
echo $folder
fi
done
IFS=$C_IFS
0
To avoid problems with white space, find
and IFS
magic (filenames can actually contain newlines as well, so IFS=$'\n'
is not a silver bullet), one could use globs and arrays.
#!/bin/bash
search_dir=${1:-.}
shopt -s globstar dotglob
for svn_dir in "$search_dir"/**/.svn/; do
base_dir=${svn_dir%/.svn/}
base_dir_contents=("$base_dir"/*)
if [ ${#base_dir_contents[@]} -eq 1 ]; then
printf 'The directory "%s" only contains ".svn/".\n' "$base_dir"
fi
done
globstar
enables the directory traversing **
construct.dotglob
includes hidden files in asterisk globs.for
glob should be safe against any problematic directory name characters. Globs will always expand safely in Bash, which is not the case with ls
, find
, etc. The trailing slash makes sure we only match folders named .svn
and not regular files (a real corner case, though)..svn
directory are globbed into an array. If the number of items in this array is 1 (i.e. the .svn
folder that we by construction know* is there), then it is what we are looking for.It only uses Bash built-ins and thus should be faster than issuing extra system forks for find
, but the difference is most likely not noticeable, and I/O will be the main bottleneck anyway.
*: Minor sidenote (applies to the other solutions as well): there is a potential race condition if there is e.g. only the .svn
and the foo
file in a directory, and the .svn
directory is removed between the for
and the array glob which would result in foo
being removed as well. However, if someone with malicious intent has the privilege to remove files in the file system, the game is probably already lost, and they could easier be removed directly than through timing attacks.
Another quick mention is that the other answers should quote their *.svn*
expansions. Otherwise the find
command will fail if the current folder contains a file that matches that glob:
$ mkdir foo && cd foo
$ mkdir -p test1/.svn test2
$ find -type d ! -path *.svn*
.
./test1
./test2
$ touch foo.svnbar
$ find -type d ! -path *.svn*
.
./test1
./test1/.svn
./test2
$ find -type d ! -path "*.svn*"
.
./test1
./test2
Without quotes, *.svn*
will be prematurely expanded by the shell to foo.svnbar
.
Are the
.svn
directories empty? – Paused until further notice. – 2011-02-25T15:31:16.603No, they are not. I think Ollis solution will work. However, I did not test it yet. – atamanroman – 2011-02-25T15:53:57.600