Find directories that do not contain subdirectories
If you are able to use find
and if you are working on a "normal Unix filesystem" (that is, as defined in find(1) under -noleaf option description), then the following command can be used:
find . -type d -links 2
Each directory has at least 2 names (hard links): .
and its name. Its subdirectories, if any, will have a ..
pointing to the parent directory, so a directory with N subdirectories will have hard link count equal to N+2. Thus, searching for directories with hard link count equal to 2, we search for directories with N=0 subdirectories.
So, if you can use find
, this is arguably the fastest method and obviously superior to in-shell loops over the directory contents stat()
'ing each of its members.
*/
matches the subdirectories of the current directory. This includes symbolic links to directories, which you may or may not desire.
In ksh93, adding ~(N)
at the beginning of the pattern makes it expand to the empty list if there is no match. Without this, the pattern remains unchanged if there is no match.
The following ksh93 function lists the subdirectories of the current directories that do not contain any subdirectory or link to a directory.
list_leaf_directories () {
local FIGNORE='.?(.)' # don't ignore dot files
local d
for d in */; do
[[ -L $d ]] || continue; # skip symbolic links
set -- ~(N)"$d"/*/
if ((!$#)); then echo "$d"; fi
done
done
You don't need to use awk
at all. Use the built-in tests that ksh
provides, something like this:
#!/bin/ksh
for NAME in *
do
FOUND=no
if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
then
for SUBNAME in $NAME/*
do
if [[ -d $SUBNAME ]]
then
FOUND=yes
break
fi
done
if [[ $FOUND == no ]]
then
echo Found only files in $NAME
fi
fi
done
That little script looks in all the directories in the current directory, and tells you if they only contain files, no sub-directories.