Например, я ищу файлы и каталоги в некотором каталоге:
ubuntu@example:/etc/letsencrypt$ sudo find . -name example.com*
./archive/example.com
./renewal/example.com.conf
./live/example.com
ubuntu@example:/etc/letsencrypt$
Как я могу это отметить ./archive/example.com
и ./live/example.com
есть ли каталоги в выводе выше?
решение1
Распечатать тип файла вместе с именем можно с помощью -printf "%y %p\n"
:
$ sudo find . -name 'example.com*' -printf "%y %p\n"
d ./archive/example.com
f ./renewal/example.com.conf
d ./live/example.com
Использование -printf
предполагает GNU find
(наиболее распространенная find
реализация в системах Linux).
решение2
Найти дважды:
echo 'directories'
find . -name 'example.com*' -type d
echo 'non-directories'
find . -name 'example.com*' ! -type d
Обратите внимание также на кавычки шаблона, используемого для проверки имени. Без кавычек оболочка попытается сопоставить строку с именами в текущем каталоге перед вызовом find
. Если failglob
опция оболочки была установлена в bash
оболочке или если NOMATCH
опция оболочки в zsh
не была отключена, шаблон подстановки без кавычек, который ничему не соответствует, сгенерирует ошибку оболочки и find
не будет вызван вообще.
В качестве альтернативы можно просто вывести косую черту в конце пути к каталогу (так ls -p
будут представлены каталоги):
find . -name 'example.com*' \( -type d -exec printf '%s/\n' {} \; -o -print \)
Вышеуказанная find
команда сначала проверяет, что имя правильное. Если это так и это каталог, она вызывается printf
для вывода пути к каталогу со слешем в конце. Если это не каталог, -print
используется для простого вывода пути как есть.
С помощью GNU find
этот -exec printf '%s/\n' {} \;
бит можно заменить на -printf '%p/\n'
.
При использовании standard find
вы также можете -exec printf '%s/\n' {} +
вызывать внешнюю printf
утилиту как можно реже, но это будет означать, что каталоги, скорее всего, будут выводиться в последнюю очередь или, по крайней мере, пакетами.
Другой альтернативой является использование для того, ls -p
чтобы отличить каталоги от других типов файлов. При использовании ls -p
каталог будет указан с конечным /
символом, как и выше.
find . -name 'example.com*' -exec ls -f -d -p {} +
Я использую -f
здесь, чтобы избежать ls
сортировки вывода и -d
чтобы избежать перечислениясодержаниекаталогов.
Вы могли бы использовать ls -F
вместо ls -p
to также поставитьдругойметки на типах файлов, отличных от каталогов. Например, исполняемые файлы будут иметь суффикс *
, а символические ссылки будут иметь суффикс @
.
Оба -p
варианта -F
(и -f
и -d
) являются стандартными опциями утилиты ls
.
решение3
Вы можете использовать file
так:
sudo find . -name "example.com*" -print0 | xargs -0 sudo file
Пример вывода:
$ sudo find . -name "example.com*" -print0 | xargs -0 sudo file
./example.com. big file: ASCII text
./example.com-dir: directory
./example.com: empty
решение4
Если вам нужен более портативный вариант, который будет работать с версиями *nix без -printf
опции gnu (например, macOS), вы можете добавить косую черту в конец пути к каталогам следующим ls
образом:
find . -name "example.com*" -exec ls -dF {} \;
пример:
$ sudo find . -name "example.com*" -exec ls -dF {} \;
./archive/example.com/
./renewal/example.com.conf
./live/example.com/
Это также оказывается в формате, более подходящем для дальнейшей передачи большему количеству команд Unix.