Поиск файлов
В логической файловой системе ОС UNIX - тысячи файлов, поэтому необходимы средства поиска файлов по различным критериям. Для поиска файлов предназначена команда find со следующим синтаксисом:
find каталог ... выражение
Утилита find просматривает иерархии каталогов в поисках файлов, удовлетворяющих критерию, задаваемому выражением. Выражения строятся из элементов с использованием следующих конструкций:
( элемент )
Истинно, если истинен элемент в скобках (поскольку скобки - метасимвол командного интерпретатора, их надо экранировать). Скобки используются для группировки элементов.
! элемент
Истинно, если элемент не истинен.
элемент [-a] элемент
Истинно, если истинны оба элемента. Если элементы просто перечислены подряд, предполагается эта же логическая операция И.
элемент -o элемент
Истинно, если истинен хотя бы один элемент.
Имена найденных (удовлетворяющих критерию, задаваемому выражением) файлов по умолчанию выдаются в стандартный выходной поток.
В качестве элементов выражения используются основные конструкции, представленные в табл. 12. Выражение проверяется слева направо, с учетом скобок.
Таблица 12. Основные элементы выражения в команде find
Элемент | Назначение или критерий истинности |
-name шаблон | Истинен, если имя файла соответствует шаблону. При использовании метасимволов необходимо маскировать шаблоны от командного интерпретатора. |
-type тип | Истинен, если файл - указанного типа. Типы файлов задаются символами b, c, d, f, l, p и s, обозначающими, соответственно, специальное блочное устройство, специальное символьное устройство, каталог, обычный файл, символьную связь, именованный канал и сокет. |
-user пользователь | Истинен, если файл принадлежит пользователю, указанному по идентификатору или регистрационному имени. |
-group группа | Истинен, если файл принадлежит группе, указанной по идентификатору или имени. |
-perm [-]права | Если дефис не задан, то истинен только если права доступа в точности соответствуют указанным (как в команде chmod, проще - абсолютные). Если задан дефис, истинен, если в правах доступа файла, как минимум, установлены те же биты, что и в указанных правах. |
-size n[c] | Истинен, если файл имеет длину n блоков (блок - 512 байтов) или символов (если указан суффикс c). Перед размером можно указывать префикс + (не меньше), - (не больше) или = (в точности равен). |
-atime n | Истинен, если к файл последний раз обращались n дней назад. Перед n в элементах -atime, -ctime и -mtime можно указывать префикс + (не позже), - (не ранее) или = (ровно). |
-ctime n | Истинен, если файл создан n дней назад. |
-mtime n | Истинен, если файл был изменен n дней назад. |
-newer файл | Истинен, если файл - более новый, чем указанный. |
-ls | Всегда истинен. Выдает информацию о файле, аналогичную длинному листингу. |
Истинен всегда. Выдает полное имя файла в стандартный выходной поток. | |
-exec команда {} \; | Истинен, если выполненная команда возвращает код возврата 0. Команда заканчивается замаскированной точкой с запятой. В команде можно использовать конструкцию {}, заменяемую полным именем рассматриваемого файла. |
-ok команда {} \; | Аналогичен exec, но полученная после подстановки имени файла вместо {} команда выдается с вопросительным знаком и выполняется только если пользователь ввел символ y. |
-depth | Истинен всегда. Требует так обходить иерархию каталогов, чтобы файлы любого каталога всегда обрабатывались раньше, чем сам каталог (обход "в глубину"). |
-prune | Истинен всегда. Требует не проверять файлы в каталоге, сопоставившемся с предыдущим элементом выражения. Не действует, если ранее указан элемент -depth. |
В различных версиях ОС UNIX могут поддерживаться и другие компоненты выражений в команде find. Если командная строка сформирована неправильно, команда немедленно завершает работу.
Рассмотрим несколько примеров использования команды find:
[kravchuk@arturo 15:05:25 /tmp]$ find . -user kravchuk -size +0c -ls find: cannot read dir ./smc898: Permission denied 475898122 4 -rw-r--r-- 1 kravchuk 50 666 Mar 26 16:58 ./-1 473866040 4 -rw-r--r-- 1 kravchuk 50 6 Mar 26 17:55 ./1.txt 475472259 4 dr-xr--r-- 2 kravchuk 50 108 Mar 26 17:39 ./d1 474199552 4 -rw-r--r-- 1 kravchuk 50 639 Mar 26 16:55 ./d1/f3.txt 476732956 4 -rw-r--r-- 1 kravchuk 50 6 Mar 26 17:55 ./2.txt 476732980 4 -rw-r--r-- 1 kravchuk 50 12 Mar 26 17:56 ./3.txt 476142563 4 -rw-r--r-- 1 kravchuk 50 7 Mar 26 17:56 ./4.txt [kravchuk@arturo 15:26:41 /tmp]$ find . -name "??.txt" -print find: cannot read dir ./smc898: Permission denied ./d1/f3.txt ./f1.txt [kravchuk@arturo 15:26:58 /tmp]$ find . -name d1 -prune -name "??.txt" -print find: cannot read dir ./smc898: Permission denied [kravchuk@arturo 15:27:09 /tmp]$ find . -name d1 -prune -o -name "??.txt" -print find: cannot read dir ./smc898: Permission denied ./f1.txt [kravchuk@arturo 15:27:13 /tmp]$ find . -user kravchuk -ok rm {} \; find: cannot read dir ./smc898: Permission denied < rm ... ./p1 >? y < rm ... ./-1 >? y < rm ... ./1.txt >? y < rm ... ./mpDfa4ZT >? y < rm ... ./d1 >? y rm: Unable to remove directory ./d1: File exists < rm ... ./d1/f3.txt >? y < rm ... ./2.txt >? y < rm ... ./3.txt >? y < rm ... ./4.txt >? y < rm ... ./f1.txt >? y [kravchuk@arturo 15:28:35 /tmp]$ find . -user kravchuk -print find: cannot read dir ./smc898: Permission denied ./d1 ./d1/f3.txt