Команда 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 могут использоваться дополнительные модификаторы:
Помимо проверок утилита позволяет выполнять определенные действия по отношению к найденным файлам. Наиболее важные действия приведены в таблице.
Действие | Назначение |
-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. |
Выводит полное имя файла, завершающееся символом перехода на новую строку, всегда возвращая логическое значение 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