Команда find

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

Базовый синтаксис команды выглядит следующим образом:

$ find [параметры] [директория…] [выражение]

В случае утилиты find параметры используются достаточно редко: они позволяют регламентировать обработку символьных ссылок, задать уровень оптимизации выражения и передать параметры отладки. Так, параметр -P позволяет запретить переход по символьным ссылкам, параметр -L — разрешить переход по символьным ссылкам, а параметр -H — запретить переход по символьным ссылкам за исключением случаев обработки выражений, например, когда в качестве имени файла для сравнения используется символьная ссылка. Параметр -O позволяет задать уровень оптимизации выражения из диапазона от 0 до 3 и в подавляющем большинстве случаев не используется, как и параметр -D, предназначенный для передачи параметров отладки утилите.

Утилита может принимать неограниченное количество путей к директориям для поиска файлов, но чаще всего ей передается путь к единственной директории. Если не указано ни одного пути к директории, утилита будет искать файлы в текущей директории.

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

Параметры выражения позволяют воздействовать на всю операцию, а не на обработку отдельного файла и всегда возвращают логическое значение true. По описанным причинам они должны располагаться в начале выражения. Наиболее важные параметры выражения приведены в таблице.

Параметр выражения Назначение
-daystart Измерять время (для проверок -amin, -atime, -cmin, -ctime, -mmin, -mtime) с начала текущего дня, а не с 24 часов назад.
-depth Обрабатывать содержимое директорий до самих директорий.
-follow Переходить по символьным ссылкам.
-help Вывести справочную информацию и выйти.
-ignore-readdir-race Не выводить сообщение об ошибке, если файл был удален после чтения содержимого директории, но до использования вызова stat для получения его параметров.
-maxdepth x Осуществлять поиск в не более, чем x поддиректориях заданных директорий.
-mindepth x Осуществлять поиск в не менее, чем x поддиректориях заданных директорий.
-regextype type Использовать тип type регулярных выражений (emacs (по умолчанию), posix-awk, posix-basic, posix-egrep, posix-extended)
-version Вывести информацию о версии и выйти.
-warn/-nowarn Выводить/не выводить предупреждения.
-xdev Не исследовать директории на других файловых системах.

Утилита поддерживает достаточно много выражений-проверок, возвращающих логические значения true и false. Чаще всего используется проверка -name для поиска файлов с заданным именем, но существует и множество других проверок, самые важные из которых приведены в таблице ниже.

Проверка Назначение
-amin x Файл открыт x минут назад
-anewer file Файл открыт после открытия файла file
-atime x Файл открыт ранее, чем x дней назад
-cmin x Файл модифицирован x минут назад
-cnewer file Файл модифицирован после файла file
-ctime x Файл модифицирован ранее, чем x дней назад
-empty Файл пуст
-executable Файл является исполняемым
-false Возврат логического значения false
-fstype fs Файл расположен на файловой системе fs
-gid id Файлом владеет группа пользователей с идентификатором id
-group group Файлом владеет группа пользователей с именем group
-ilname name Символьная ссылка имеет имя name без учета регистра
-iname name Файл имеет имя name без учета регистра
-inum x Файл связан со структурой inode с номером x
-ipath path В пути к файлу присутствует фрагмент path без учета регистра
-iregex regex Путь к файлу соотвествует регулярному выражению regex без учета регистра
-links x Файл имеет x символьных ссылок
-lname name Символьная ссылка имеет имя name
-mmin x Файл модифицирован x минут назад
-mtime x Файл модифицирован x дней назад
-name name Файл имеет имя name
-newer file Файл модифицирован после файла file
-nogroup Файлом не владеет ни одна из существующих групп пользователей
-nouser Файлом не владеет ни один из существующих пользователей
-path path В пути к файлу присутствует фрагмент path
-perm perm Файл имеет права доступа perm
-readable Файл доступен для чтения
-regex regex Путь к файлу соотвествует регулярному выражению regex
-samefile file Файл связан с той же структурой inode, что и файл file
-size x Файл имеет размер x байт (для указания размера в других единицах используются модификаторы: b — 512-байтовые блоки, c — байты, w — двухбайтовые слова, k — килобайты, M — мегабайты, G — гигабайты)
-true Возврат логического значения true
-type type Файл относится к указанному типу type (b — блочное устройство, c — символьное устройство, d — директория, p — именованный канал FIFO, f — обычный файл, l — символьная ссылка, s — сокет)
-uid id Файлом владеет пользователь с идентификатором id
-user user Файлом владеет пользователь с именем user
-writable Файл доступен для записи

В случае числовых значений x могут использоваться дополнительные модификаторы:

  • +x — значение, большее x
  • -x — значение, меньшее x
  • x — ровно x

Помимо проверок утилита позволяет выполнять определенные действия по отношению к найденным файлам. Наиболее важные действия приведены в таблице.

Действие Назначение
-delete Удалять найденные файлы. В случае корректного удаления возвращает true, в противном — false.
-exec command ; Выполнять команду command по отношению к каждому из найденных файлов. Возвращает true в случае получения нулевого статуса завершения команды, false — в противном случае. Последовательность {} заменяется на имя текущего файла, параметры команды задаются до символа ;.
-exec command {} + Вариант действия exec, в котором осуществляется объединение имен найденных файлов в рамках одной команды. Таким образом снижается количество создаваемых процессов.
-execdir command ; Аналог действия exec, исполняющий команду в поддиректории с найденным файлом.
-execdir command {} + Вариант действия execdir, в котором осуществляется объединение имен найденных файлов в рамках одной команды. Таким образом снижается количество создаваемых процессов.
-fprint file Записывает полное имя файла, завершающееся символом перехода на новую строку, в файл с именем file, всегда возвращая логическое значение true.
-fprintf file format Аналог действия printf, записывающий вывод в файл с именем file. Файл создается всегда, даже если в него не записывается имен файлов.
-ok command ; Вариант действия exec, в котором пользователю предлагается согласиться или отказаться от выполнения действия. В случае отказа возвращается логическое значение false.
-okdir command ; Вариант действия execdir, в котором пользователю предлагается согласиться или отказаться от выполнения действия. В случае отказа возвращается логическое значение false.
-print Выводит полное имя файла, завершающееся символом перехода на новую строку, всегда возвращая логическое значение true.
-printf format Выводит строку в заданном формате, всегда возвращая логическое значение true. Строка форматирования формируется по аналогии со строками форматирования языка C, но имеется множество нюансов, которые позволяют выводить информацию о найденных файлах.
-quit Немедленно завершает работу утилиты.

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

Оператор Назначение
( expr ) Исполнять выражение expr в первую очередь. Так как скобки являются специальными символами командной оболочки, следует использовать символы для экранирования.
! expr Возвращает логическое значение true, если результатом исполнения выражения expr является логическое значение false (логическое «не»). Символ восклицательного знака также должен экранироваться.
-not expr Аналог оператора !, совместимый с POSIX.
expr1 expr2 Два выражения объединяются с помощью неявного оператора -and (логическое «и»), то есть, expr2 не выполняется в том случае, если в результате исполнения expr1 получено логическое значение false.
expr1 -a expr2 Аналог expr1 expr2.
expr1 -and expr2 Аналог expr1 expr2, совместимый с POSIX.
expr1 -o expr2 Возвращает логическое значение true, если результатом исполнения выражения expr1 или expr2 является значение true и false в противном случае (логическое «или»).
expr1 -or expr2 Аналог expr1 -o expr2, совместимый с POSIX.
expr1, expr2 При использовании запятой оба выражения будут исполняться всегда. В качестве результата будет использоваться результат исполнения выражения expr2.

Примеры использования

Вывод списка всех файлов в файловой системе

Для вывода списка всех доступных файлов может использоваться утилита find без каких-либо параметров.

$ find
.
./debian.patch
./Изображения

Поиск файлов без учета регистра имен

Для игнорирования регистра имен файлов следует использовать проверку -iname вместо -name. Например, для поиска файлов myClass.h, MyClass.h и так далее следует использовать команду:

$ find -iname myClass.h

Удаление найденных файлов

Если вам нужно удалить все найденные временные файлы с расширением .old, вы можете воспользоваться следующей командой:

$ find -type f -name "*.old" -delete

Учтите, что все файлы будут удалены, а не помещены в корзину, поэтому следует использовать данную команду с особой осторожностью.

Поиск файлов с заданным содержимым

Для поиска файлов с заданной строкой достаточно объединить функции утилит find и grep. В этом нет ничего сложного — достаточно использовать аналогичную команду:

$ find . -exec grep -H "Hello World" {} ;

grep: .: Это каталог
./main.d:    MainWindow win = new MainWindow("Hello World");
./main.d:    win.add(new Label("Hello World"));
grep: ./other: Это каталог

Символ точки с запятой является управляющим символом командной оболочки и должен экранироваться.

Поиск непустых файлов

Для поиска непустых файлов достаточно использовать оператор «не» и проверку пустого файла:

$ find -not -empty
.
./splash1280.jpg
./main.d
./other
./other/Better_Red_Than_Dead.rar
./nolf228.jpg
./splash1024.jpg