find - обход и поиск по иерархии файлов

find [-H | -L | -P] [-EXdsx] [-f путь ] путь ... выражение
find [-H | -L | -P] [-EXdsx] -f путь [ путь ...] выражение

Программа find рекурсивно обходит дерево директорий каждого пути, указанного аргументами путь, вычисляя выражение ( состоящее из перечисленных ниже примитивов и операндов ) для каждого файла в текущем дереве директорий файловой системы. Наверное одна из полезнейших программ для администрирования системы.

Имеются следующие опции:

-E
Интерпретировать регулярные выражения в примитивах -regex и -iregex как расширенные регулярные выражения вместо базовых регулярных выражений (BRE). Страница справочника re_format(7) полностью описывает оба формата.
-H
Возвращать информацию о файле и его типе (см. stat(2)) для файлов, на которые указывают заданные в командной строке символические ссылки, а не для самих ссылок. Если файл, на который указывает ссылка, не существует, будет выведена информация для самой ссылки. Информация о файле для символической ссылки не из командной строки будет возвращаться для самих ссылок.
-L
Возвращать информацию о файле и его типе (см. stat(2)) для файлов, на которые указывают символические ссылки, а не для самих ссылок. Если файл, на который указывает ссылка, не существует, будет выведена информация для самой ссылки.

Эта опция эквивалентна устаревшему примитиву -follow.

-P
Возвращать информацию о файле и его типе (см. stat(2)) для каждой символической ссылки о самой ссылке. Это поведение по умолчанию.
-X
Позволить безопасное использование find совместно с xargs(1). Если имя файла содержит любой из символов-разделителей, используемых xargs(1), вывести диагностическое сообщение в стандартный файл ошибок и пропустить файл. Символы-разделители включают в себя одиночные и двойные кавычки, обратную косую черту ( \ ), пробел, табуляцию и символ перевода строки.

Однако вы можете использовать примитив -print0 совместно с xargs -0' как эффективную альтернативу.

-d
Заставить find производить обход сначала в глубину, т.е. директории проходятся в пост-порядке, и все элементы каталога обрабатываются перед самой директорией. По умолчанию, find проходит директории в пред-порядке, т.е. перед их содержимым.

Данная опция эквивалентна примитиву -depth из IEEE Std 1003.1-2001(``POSIX.1'') . Опция -d может быть полезной, когда find используется совместно с cpio(1) для обработки файлов в директориях с необычными правами доступа.

-f
Указать find иерархию файлов для обхода. Иерархии файлов могут быть указаны как операнды, следуя непосредственно за опциями.
-s
Заставить find обходить файловые иерархии в лексикографическом порядке, т.е. в алфавитном порядке в каждом каталоге.

Примечание: find -s и find | sort могут давать разные результаты.

-x
Запретить find спускаться в каталоги, имеющие номер устройства, отличный от такового у файла, с которого начался обход.
Эта опция эквивалентна устаревшему примитиву -xdev.

Примитивы

-Bmin n
Истинен, если разница между временем создания индексного дескриптора ( inode ) файла и временем запуска find, округлённая до следующей полной минуты, равна n минут.
-Bnewer файл
То же, что и -newerBm.
-Btime n[smhdw]
Если единицы времени не указаны, то этот примитив истинен, если разница между временем создания индексного дескриптора ( inode ) файла и временем запуска find, округлённая до следующего полного 24-часового периода, составляет n 24-часовых периодов.

Если единицы времени указаны, то этот примитив истинен, если разница между временем создания индексного дескриптора ( inode ) файла и временем запуска find в точности равна n единиц. Обратитесь к описанию примитива -atime для информации о поддерживаемых единицах времени.

-acl
Может быть использован совместно с другими примитивами для поиска файлов с расширенными ACL. Обратитесь к acl(3) для получения более подробной информации.
-amin n
Истинен, если разница между временем последнего доступа к файлу и временем запуска find, округлённая до следующей полной минуты, составляет n минут.
-anewer файл
То же, что и -neweram.
-atime n[smhdw]
Если единицы времени не указаны, то этот примитив истинен, если разница между временем последнего доступа к файлу и временем запуска find, округлённая до следующего полного 24-часового периода, составляет n 24-часовых периодов.

Если единицы времени указаны, то этот примитив истинен, если разница между временем последнего доступа к файлу и временем запуска find в точности равна n единиц. Допустимые единицы времени:

             s       секунда
             m       минута (60 секунд)
             h       час (60 минут)
             d       день (24 часа)
             w       неделя (7 дней)

В одном аргументе -atime могут быть скомбинированы произвольные единицы времени, например: -atime -1h30m. Единицы времени скорее всего будут полезны только в сочетании с модификатором + или -.

-cmin n
Истинен, если разница между временем последнего изменения статусной информации о файле и временем запуска find, округлённая до следующей полной минуты, равна n минут.
-cnewer файл
То же, что и -newercm.
-ctime n[smhdw]
Если единицы времени не указаны, то этот примитив истинен, если разница между временем последнего изменения статусной информации о файле и и временем запуска find, округлённая до следующего полного 24-часового периода, составляет n 24-часовых периодов.

Если единицы времени указаны, то этот примитив истинен, если разница между временем последнего изменения статусной информации о файле и временем запуска find в точности равна n единиц. Обратитесь к описанию примитива -atime для информации о поддерживаемых единицах времени.

-delete
Удалить найденные файлы и/или каталоги. Всегда истинен. Исполняется из текущего рабочего каталога, по мере рекурсивного прохода find вниз по дереву. Исходя из соображений безопасности, find не будет пытаться удалять файлы с символом / в пути относительно текущей директории. Эта опция подразумевает обход сначала в глубину.
-depth
Всегда истинен; то же, что и опция -d.
-depth n
Истинен, если глубина файла относительно точки начала обхода равна n.
-empty
Истинен, если текущий файл или каталог пусты.
-exec имя_программы [аргумент ...] ;
Истинен, если программа с именем имя_программы возвращает нулевое значение в качестве статуса завершения. Программе могут быть переданы необязательные аргументы. Выражение должно завершаться точкой с запятой ( ; ). Если вы запускаете find из командной оболочки ( shell ), вам может потребоваться экранировать точку с запятой, поскольку в противном случае командная оболочка может воспринять её как управляющий оператор. Если где-либо в имени программы или в аргументах появляется строка {}, то она заменяется на путь текущего файла. Программа будет запущена из каталога, в котором был запущен find. Аргументы имя_программы и аргумент не подвержены дальнейшему раскрытию шаблонов и конструкций командной оболочки.
-exec имя_программы [аргумент ...] {} +
То же, что и -exec, за исключением того, что {} заменяется максимально возможным количеством путей при каждом запуске утилиты. Это поведение аналогично таковому у xargs(1).
-execdir имя_программы [аргумент ...] ;
Примитив -execdir идентичен примитиву -exec за исключением того, что программа с именем имя_программы будет запущена из каталога, содержащего текущий файл. Имя файла, подставляемого вместо строки {}, не содержит пути к нему.
-flags [-|+]flags,notflags
Флаги задаются указанием символических имён (см. chflags(1)). О флагах с префиксом no ( за исключением nodump ) говорят, что это notflags ( отрицания флагов ). Проверяется, что флаги в наборе flags установлены, а флаги в наборе notflags сброшены. Заметьте, что это отличается от примитива -perm, позволяющего пользователю указать лишь те биты, которые установлены.

Если флагам предшествует минус ( - ), то этот примитив будет истинным, если среди флагов файла установлены по крайней мере все биты из набора flags и не установлен ни один бит из набора notflags. Если флагам предшествует плюс ( + ), то этот примитив будет истинным, если среди флагов файла установлен любой из битов набора flags, или не установлен любой из битов набора notflags. В противном случае, этот примитив будет истинным, если биты в наборе flags в точности соответствуют флагам файла, и ни один из битов набора flags не указан в наборе notflags.

-fstype тип
Истинен, если файл содержится в файловой системе типа тип. Для получения доступных в системе типов файловых систем можно воспользоваться командой sysctl(8):

sysctl vfs

Кроме того, имеются два псевдо-типа, local и rdonly.
Первый задаёт любую файловую систему, физически смонтированную на машине, где запускается find, а второй обозначает любую файловую систему, смонтированную только для чтения.

-group имя_группы
Истинен, если файл принадлежит группе с именем имя_группы. Если аргумент имя_группы задан в числовом виде, и не существует такого имени группы, то аргумент имя_группы трактуется как идентификатор группы ( group ID ).
-iname шаблон
Подобен -name, но сравнение не учитывает регистр.
-inum номер
Истинен, если номер индексного дескриптора ( inode ) файла равен номер.
-ipath шаблон
Подобен -path, но сравнение не учитывает регистр.
-iregex шаблон
Подобен -regex, но сравнение не учитывает регистр.
-links n
Истинен, если файл имеет n жёстких связей.
-ls
Этот примитив всегда истинен. Для текущего файла в стандартный вывод пишется следующая информация: номер индексного дескриптора ( inode ), размер в 512-байтных блоках, права доступа к файлу, число жёстких связей ( hard links ), владелец, группа, размер в байтах, время последнего изменения и путь. Если файл представляет собой специальный файл блочного или символьного устройства, вместо размера выводятся старший ( major ) и младший ( minor ) номера устройства. Если файл является символической ссылкой, то после знака -> будет также выведен путь к указываемому файлу. Этот формат идентичен используемому в ls -dgils.
-maxdepth n
Всегда истинен; заставляет спускаться не более чем на n уровней каталогов ниже аргументов командной строки. Если присутствует примитив -maxdepth, он применяется ко всему выражению, даже если в нормальных условиях он бы не вычислялся. -maxdepth 0 ограничивает весь поиск исключительно аргументами командной строки.
-mindepth n
Всегда истинен; не применять любые тесты или действия на уровнях меньше n. Если присутствует примитив -mindepth, он применяется ко всему выражению, даже если в нормальных условиях он бы не вычислялся. -mindepth 1 обрабатывает всё, кроме аргументов командной строки.
-mmin n
Истинен, если разница между временем последнего изменения файла и временем запуска find, округлённая до следующей полной минуты, равна n минут.
-mnewer файл
То же, что и -newer.
-mtime n[smhdw]
Если единицы времени не указаны, то этот примитив истинен, если разница между временем последнего изменения файла и временем запуска find, округлённая до следующего полного 24-часового периода, составляет n 24-часовых периодов.

Если единицы времени указаны, то этот примитив истинен, если разница между временем последнего изменения файла и временем запуска find в точности равна n единиц. Обратитесь к описанию примитива -atime для информации о поддерживаемых единицах времени.

-name шаблон
Истинен, если последний компонент пути файла (его имя) подпадает под шаблон. В шаблоне могут быть использованы специальные шаблонные символы командной оболочки ( [, ], *, и ? ). Эти символы могут быть заданы для проверки на совпадение явным образом с помощью экранирования их символом обратной косой черты ( \ ).
-newer файл
Истинен, если текущий файл имеет более позднее время последнего изменения, чем файл.
-newerXY файл
Истинен, если текущий файл имеет более позднее время последнего доступа (X=a), время создания индексного дескриптора ( inode ), т.е. самого файла (X=B), время последнего изменения индексного дескриптора ( X=c ) или время последнего изменения файла ( X=m ), нежели время последнего доступа ( Y=a ), время создания индексного дескриптора ( Y=B ), время изменения индексного дескриптора ( Y=c ) или время изменения ( Y=m ) файла файл. Кроме того, если Y=t, то аргумент файл будет интерпретирован не как файл, а как непосредственное указание даты в форме, понятной cvs(1). Можно заметить, что использование -newermm эквивалентно использованию -newer.
-nogroup
Истинен, если файл принадлежит неизвестной группе.
-nouser
Истинен, если файл принадлежит неизвестному пользователю.
-ok имя_программы [аргумент ...] ;
Примитив -ok идентичен примитиву -exec, за исключением того, что find запросит у пользователя подтверждение на выполнение программы с именем имя_программы выводом сообщения на терминал и ожиданием ответа. Если ответ не был утвердительным ( "y" в локали ( locale ) "POSIX ), команда не исполняется, и значение примитива -ok будет ложным.
-okdir имя_программы [аргумент ...] ;
Примитив -okdir идентичен примитиву -execdir, с тем же исключением, что было описано для примитива -ok.
-path шаблон
Истинен, если рассматриваемый путь подпадает под шаблон. В шаблоне можно использовать специальные шаблонные символы командной оболочки ( [, ], *, и ? ). Эти символы могут быть заданы для проверки на совпадение явным образом с помощью экранирования их символом обратной косой черты ( \ ). Прямая косая черта ( / ) рассматривается как обычный символ и не требует явного указания для совпадения.
-perm [-|+]режим
Права доступа в аргументе режим могут быть заданы либо символически (см. chmod(1)), либо восьмеричным числом. Если режим задан символически, стартовым значением полагается ноль, и режим устанавливает или сбрасывает права без учёта маски создания файлов процесса. Если режим задан восьмеричным числом, то только биты 07777 ( S_ISUID | S_ISGID | S_ISTXT | S_IRWXU | S_IRWXG | S_IRWXO ) участвуют в сравнении с правами доступа файла. Если перед аргументом режим указан минус ( - ), то этот примитив будет истинным, если по крайней мере все биты в аргументе режим установлены в правах доступа файла. Если перед аргументом режим указан плюс ( + ), то этот примитив будет истинным, если любой из битов в аргументе режим установлен в правах доступа файла. В противном случае, этот примитив будет истинным только при точном совпадении битов в аргументе режим с правами доступа текущего файла. Обратите внимание, что минус ( - ) не может быть первым символом при символическом задании прав.
-print
Этот примитив всегда истинен. Он выводит путь текущего файла в стандартный вывод. Если не указан ни один из примитивов -exec, -ls, -print0 или -ok, то заданное выражение фактически будет заменено на -print.
-print0
Этот примитив всегда истинен. Он выводит путь текущего файла в стандартный вывод, и следом за ним символ ASCII NUL (символ с кодом 0).
-prune
Этот примитив всегда истинен. Он заставляет find не спускаться в текущий файл. Необходимо отметить, что примитив -prune не действует при указании опции -d.
-regex шаблон
Истинен, если полный путь файла подпадает под регулярное выражение шаблон. Для задания файла, именуемого ./foo/xyzzy, можно использовать регулярные выражения .*/[xyz]* или .*/foo/.*, но не xyzzy и не /foo/.
-size n[ckMGTP]
Истинен, если размер файла в 512-байтных блоках, при округлении вверх, равен n. Если за n следует c, то примитив будет истинным, если размер файла равен n байт (символов). Аналогично, если за n следует буква множителя, тогда размер файла сравнивается с n, помноженным на одно из следующих:

             k       килобайт (1024 байта)
             M       мегабайт (1024 килобайта)
             G       гигабайт (1024 мегабайта)
             T       терабайт (1024 гигабайта)
             P       петабайт (1024 терабайта)
-type тип
Истинен, если типом текущего файла является тип. Возможные типы файлов:

             b       блочный специальный
             c       символьный специальный
             d       каталог
             f       обычный файл
             l       символическая ссылка
             p       именованный канал (FIFO)
             s       сокет
-user имя_пользователя
Истинен, если файл принадлежит пользователю с именем имя_пользователя. Если имя_пользователя задано в числовом виде и такого имени пользователя не существует, то аргумент имя_пользователя трактуется как идентификатор пользователя (user ID).

Все примитивы, принимающие числовой аргумент, допускают задание этого числа со знаком плюс ( + ) или минус ( - ). Предшествующий плюс означает больше n', предшествующий минус означает меньше n, а отсутствие знака ровно n.

Операторы

Примитивы могут комбинироваться с использованием нижеследующих операторов. Операторы перечислены в порядке понижения приоритета.

( выражение )
Будет истинным, если истинно выражение в скобках.
! выражение
-false выражение
-not выражение
Это унарный оператор НЕ. Он будет истинным, если выражение ложно.
выражение -and выражение
выражение выражение
Оператор -and есть логический оператор И. Поскольку он подразумевается непосредственным соседством двух выражений, его не требуется указывать явно. Выражение истинно, если оба выражения истинны. Второе выражение не вычисляется, если первое выражение ложно.
выражение -or выражение
Оператор -or есть логический оператор ИЛИ. Выражение истинно, если любое из двух выражений истинно. Второе выражение не вычисляется, если первое выражение истинно.

Все операнды и примитивы должны быть отдельными аргументами find. Примитивы, имеющие собственные аргументы, ожидают их как отдельные аргументы find.

Окружение
Переменные окружения LANG, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES и LC_TIME влияют на выполнение утилиты find, как описано в environ(7).

Примеры

find / \! -name "*.c" -print
Вывести список всех файлов, имена которых не заканчиваются на .c.

find / -newer ttt -user wnj -print
Вывести список всех файлов, принадлежащих пользователю wnj, которые изменены позднее файла ttt.

find / \! \( -newer ttt -user wnj \) -print
Вывести список всех файлов, которые изменены не позднее файла ttt и одновременно не принадлежат пользователю wnj.

find / \( -newer ttt -or -user wnj \) -print
Вывести список всех файлов, которые принадлежат пользователю wnj или изменены позднее файла ttt.

find / -newerct '1 minute ago' -print
Вывести список всех файлов, индексный дескриптор которых был изменён не позднее одной минуты назад.

find / -type f -exec echo {} \;
Использовать команду echo(1) для вывода списка всех файлов.

find -L /usr/ports/packages -type l -delete
Удалить все битые символические ссылки в /usr/ports/packages.

find /usr/src -name CVS -prune -o -depth +6 -print
Найти файлы и каталоги, имеющие по крайней мере семь уровней вложенности в рабочем каталоге /usr/src.

find /usr/src -name CVS -prune -o -mindepth 7 -print 
Это не эквивалентно предыдущему примеру, поскольку -prune не выполняется ниже уровня семь.

Возможные проблемы
Специальные символы, используемые find, являются также специальными символами для многих командных оболочек. В частности, может потребоваться экранировать от командной оболочки символы *, [, ], ?, (, ), !, \ и ;.

Поскольку не существует разделителей, отделяющих опции от имён файлов или имена файлов от выражений, трудно задать файлы с именами типа -xdev или !. Эти проблемы решаются опцией -f и конструкцией -- для getopt(3).

Примитив -delete плохо взаимодействует с другими опциями, меняющими порядок обхода дерева файловой системы.

Примитивы -mindepth и -maxdepth фактически являются глобальными опциями ( как документировано выше ). Они, по-видимому, должны быть заменены опциями, выглядящими как опции.