Используйте GNU find, чтобы показывать только каталоги листьев
Я пытаюсь использовать GNU find для поиска только каталогов, которые не содержат других каталогов, но могут содержать или не содержать обычные файлы.
Моя лучшая догадка была до сих пор:
find dir -type d \( -not -exec ls -dA ';' \)
но это просто дает мне длинный список "."
Спасибо!
Ответы
Ответ 1
Вы можете использовать ссылки, если ваша файловая система совместима с POSIX (т.е. в каталоге есть ссылка для каждого подкаталога в ней, ссылка от ее родителя и ссылка на "я" ), поэтому счетчик ссылок 2, если у него нет подкаталогов).
Следующая команда должна делать то, что вы хотите:
find dir -type d -links 2
Однако он не работает в Mac OS X (как упоминал @Piotr). Вот еще одна версия, которая работает медленнее, но работает на Mac OS X. Она основана на его версии с исправлением для обработки пробелов в именах каталогов:
find . -type d -exec sh -c '(ls -p "{}"|grep />/dev/null)||echo "{}"' \;
Ответ 2
Решение @Sylvian не работало для меня на mac os x по какой-то неясной причине. Поэтому я придумал немного более прямое решение. Надеюсь, это поможет кому-то:
find . -type d -print0 | xargs -0 -IXXX sh -c '(ls -p XXX | grep / >/dev/null) || echo XXX' ;
Пояснение:
-
ls -p
завершает каталоги с помощью '/'
- поэтому
(ls -p XXX | grep / >/dev/null)
возвращает 0, если нет каталогов
-
-print0
&& & -0
означает, что xargs обрабатывает пробелы в именах каталогов
Ответ 3
Как насчет этого? Он переносится, и он не зависит от финишных ссылок. Обратите внимание, однако, что важно поставить root/folder
без конечного /.
find root/folder -type d | awk '{ if (length($0)<length(prev) || substr($0,1,length(prev))!=prev) print prev; prev=($0 "/") } END { print prev }'
Ответ 4
Вот решение, которое работает на Linux и OS X:
find . -type d -execdir bash -c '[ "$(find {} -mindepth 1 -type d)" ] || echo $PWD/{}' \;
или
find . -type d -execdir sh -c 'test -z "$(find "{}" -mindepth 1 -type d)" && echo $PWD/{}' \;