List folders which contain only a subfolder named Attic
With bash
, GNU find
, and comm
:
comm -12 \
<( find /path/to/CVS/repo -printf '%h\n' \
sort | uniq -u ) \
<( find /path/to/CVS/repo -name Attic -type d -printf '%h\n' | \
sort )
The first find
prints basename
s (-printf '%h\n'
) of everything, files and directories, in the repository. sort | uniq -u
then prints directories with exactly one descendant, file or directory.
Then the second find
prints the basename
s of the Attic
directories. The intersection of this set to the set above (i.e. comm -12
) are exactly the directories with only an Attic
descendant.
This of course happily ignores things like symlinks and other fun, and filenames with embedded newlines. You shouldn't have those in a CVS repo anyway.
Find all Attic
folders in .
without any siblings, in bash:
find . -type d -name Attic -print0 | while read -d $'\0' DIR ;\
do [[ $(ls -1 "$DIR/.." | wc -l) -eq 1 ]] && echo "$DIR" ; done
Replace echo
with your favorite file handling command ;-).
The first part seems to be easiest to do with a bit of Python:
#!/usr/bin/env python
import os, sys
for topdir in sys.argv:
for root, dirs, files in os.walk(topdir):
if not files and len(dirs) == 1 and dirs[0] == 'Attic':
print os.path.join(root)
Run it like this:
./script.py /path/to/CVS/repo
To delete the directories, assuming your files don't have newlines embedded in names, and assuming a cooperating xargs
(i.e. one with the -d
option):
./script.py /path/to/CVS/repo | xargs -d '\n' rm -rf
With a non-cooperating xargs
you could modify the script to print NUL
-terminated strings:
#!/usr/bin/env python
from __future__ import print_function
import os, sys
for topdir in sys.argv:
for root, dirs, files in os.walk(topdir):
if not files and len(dirs) == 1 and dirs[0] == 'Attic':
print(os.path.join(root), end="\0")
Then you'd use xargs -0
to kill the directories:
./script.py /path/to/CVS/repo | xargs -0 rm -rf
To kill empty directories after that:
find /path/to/CVS/repo -depth -type d -empty -delete