Учитывая тип файла .txt, найдите все каталоги, которые имеют только этот тип файла.
Например
a--
b-- 1.txt
c--
|
---- 2.jpg
---- 3.txt
Команда должна выводить только b
не c
.
Учитывая тип файла .txt, найдите все каталоги, которые имеют только этот тип файла.
Например
a--
b-- 1.txt
c--
|
---- 2.jpg
---- 3.txt
Команда должна выводить только b
не c
.
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
но это не имеет значения, потому что эти дополнительные символы новой строки могут добавить к счетчику, только если "правильное" число в любом случае ненулевое, и нам нужно только знать, является ли результат ноль или нет.