find . -type d -execdir sh -c ' [ "$(find "$1" -maxdepth 1 -type f -name "*.txt" -print -quit | wc -l)" -gt 0 ] && [ "$(find "$1" -maxdepth 1 -type f ! -name "*.txt" -print -quit | wc -l)" -eq 0 ] ' find-sh {} \; -print
Каталоги внешних find
поставок для изучения. Два внутренних параметра find
-s проверяют, есть ли в .txt
каталоге хотя бы один файл и нет ли других .txt
файлов. sh
оболочка реализует логику с [ … ]
и &&
.
Заметки:
-maxdepth
POSIX не требуется. Для подхода POSIX см. Этот вопрос .-quit
POSIX не требуется. Это действиеfind
завершает работу, как только сообщается о любом соответствующем файле. Это полезно, потому что нам нужен не более одного соответствующего файла, чтобы получить результат с,wc -l
и[ … ]
, таким образом, преждевременный выход из него экономит время. Без-quit
всей команды будет работать, она будет медленнее, когда есть много файлов. В качестве альтернативы вы можете использоватьfind … | head -n 1 | wc -l
; в этом случаеhead
прервет канал после первого найденного файла, сразу жеwc
выдаст результат, ноfind
заметит прерванный канал только тогда, когда (если) попытается написать еще одну строку. И это компромисс:head
может сэкономить вам время и ресурсы, но (как отдельный процесс) требуется время и ресурсы, которые будут порождаться дважды в каждом каталоге.- Пути с символами новой строки (если таковые имеются) будут обманывать,
wc -l
но это не имеет значения, потому что эти дополнительные символы новой строки могут добавить к счету, только если «правильное» число в любом случае ненулевое, и нам нужно только знать, равен ли результат нулю или нет ,