Главная > Операционные системы > UNIX
| 7.6. Поиск файла по заданным атрибутам | |
|---|
| Глава 7. Базовые навыки работы в Unix |  |
|---|
7.6. Поиск файла по заданным атрибутамОписание:
Утилита find(1) незаменима при поиске файлов с
заданными параметрами. Кандидат BSDA должен
свободно владеть ею. На экзамене его могут попросить найти файл с
заданным последним временем изменения, размером, типом, файловыми
флагами, UID, GID,
пермиссиями или содержащим в названии какой-то шаблон.
Практика: find(1)
Комментарий
Команда find(1) предназначена для поиска
файлов по заданному критерию. Формат команды:
find [опции] где_искать [что искать (условия)] [действие]
Опции могут быть различные, они регулируют поведение
find(1) при поиске. К тому же они в разных
версиях и в разных системах разные. Так, напрмер, опция
-E, изменяющая синтаксис регулярных выражений в
опциях -regex и -iregex
подобно аналогичной опции в grep(1), имеется
только в FreeBSD.
Пожалуй важно знать опцию -x. Она предотвращает
поиск на устройствах отличных от устройства, с которого поиск
начался. Например:
Эта команда выведет список всех файлов в домашнем каталоге
пользователя user и во всех подкаталогах, кроме каталогов
являющихся точками монтирования других устройств
(/home/user/mnt/floppy,
/home/user/mnt/cdrom,
/home/user/mnt/nfs).
Путь надо указывать обязательно. Некоторые версии
GNU find проводят поиск
относительно текущего каталога, если им не указать путь,
find в BSD требует явного указания пути. В
особых случаях, когда путь, в котором надо производить поик
имеет необычное имя, можно указать его как аргумент опции
-f.
7.6.1. Условия для поиска командой find(1)
Условия для поиска задаются опциями, перечисленными ниже. При
задании нескольких опций, они объединяются через оператор
«и». Связку «и» можно задать явно используя
опцию -and. Связка «или» задаётся
опцией -or. Унарное отрицание —
! и символы группировки —
(...), в sh и
csh необходимо защищать используя либо
кавычки, либо \.
-amin n -cmin n
-mmin n-
Условие истинно, если разница между временем когда был
запущен поиск и временем файла меньше
n
минут. Здесь под временем файла имеется ввиду:
-amin — access time (время
последнего доступа к файлу),
-cmin — change of file status
information (время изменения информации о состоянии файла)
-mtime — modification time
(время изменения файла)
-anewer file -cnewer file
-mnewer file-
Условие истинно, найденный файл моложе указанного. Здесь
под временем файла имеется ввиду:
-anewer — access time (время
последнего доступа к файлу),
-cnewer — change of file
status information (время изменения информации о состоянии
файла) -mnewer — modification
time (время изменения файла)
-atime n -ctime n
-mtime n
Условие истинно, если разница между временем когда был
запущен поиск и временем файла округлённая вверх, в
точности n суток. Здесь под временем
файла имеется ввиду: -amin —
access time (время последнего доступа к файлу),
-cmin — change of file status
information (время изменения информации о состоянии файла)
-mtime — modification time
(время изменения файла)
У времени можно задавать знак:
-mtime -7 — ищем файлы
изменённые за последнюю неделю,
-mtime +7 — ищем файлы
не менявшиеся в течение недели.
В FreeBSD имеется расширение
синтаксиса: опциям -atime,
-ctime и -mtime можно
указывать время с размерностью в секундах, минутах, часах,
днях и неделях. Например 2s,
3m, 4h,
5d, 6w. Можно
комбинировать размерности:
5d6w — шесть недель и пять
дней.
В OpenBSD и NetBSD
для аналогичного поиска придётся пользоваться опциями
-amin, -cmin и
-mmin, переводить время в минуты и
использовать где надо отрицание !.
-newer file-
Условие истинно, если найденный файл изменён позже
указанного
-newerXY file
Опция есть только в FreeBSD!
Условие истинно, если найденный файл имеет большее время
доступа (X=a), изменения статуса
(X=c), модификации (X=m)
указанного чем время доступа (Y=a),
изменения статуса (Y=c), модификации
(Y=m) у указанного файла.
-empty-
Условие истинно, если найденный файл или каталог пуст
-flags [-] flags-
Условие истинно, если найденный файл или каталог имеет
указанные флаги. Флаги являются свойством файловой системы
UFS и описаны в справочной странице
chflags(1). Если знак
- не указан, условие истинно, если флаги
в точности соответствуют указанным. Если знак
- указан, условие совпадает, если как
минимум указанные флаги присутствуют.
-perm [-] mode-
mode может быть как символьным (chmod),
так и восьмеричным.
- имеет то же
значение, что и в опции -flags.
-group group, -user user-
Условие истинно, если найденный файл принадлежит
пользователю user или группе group. Можно указавать как
имена, так и ID (если указано чисто и пользователя с таким
именем нет, оно толкуется как ID).
-nogroup, -nouser-
Условие истинно, если найденный файл принадлежит
неизвестному пользователю или неизвестной группе.
-type type
Условие истинно, если найденный файл имеет указанный тип.
Возможные типы файла:
b | block special | блочное устройство | c | character special | символьное устройство | d | directory | каталог | f | regular file | обычный файл | l | symbolic link | символьная ссылка | p | FIFO | именованный канал | s | soket | сокет |
-fstype type-
Условие истинно, если найденный файл находится на
устройстве с файловой системой типа type. Возможные типы
файловых систем можно узнать при помощи
sysctl(8)
(sysctl vfs). Кроме того, можно
использовать ключевые слова
local и
rdonly.
-[i]name pattern-
Имя файла. Можно указать шаблон с
*,
? и []. Опция
-iname отличается тем, что игнорирует
регистр.
-[i]path pattern-
Путь к файлу. Можно указывать шаблон с
*,
? и [].
/ считается обычным символом. Вариант
нечувствителоьный к регистру реализован в
FreeBSD и NetBSD.
-[i]regex pattern
Опция не реализована в OpenBSD!
Условие истинно, если имя файла (вместе с путём) полностью
соответствует регулярному выражению
pattern. Что значит полностью? Шаблон
foo не соответствует пути
./foo/bar, а .*foo.* соответствует. Вариант
-iregex нечувтвителен к регистру.
-size n[c]-
Условие истинно, если файл занимает
n
блоков по 512 байт. Внимание! команда
find(1) не использует переменную
окружения BLOCKSIZE. Если указан
суффикс c, то размер берётся точно в
байтах. Так же как и в случае с опцией
-atime можно задавать знак:
-size -1024c — искать
файлы размером меньше килобайта.
-maxdepth n и -mindepth n-
Максимальная и манимальная глубина погружения в
подкаталоги. Например:
-maxdepth 1
искать файлы только в текущем каталоге, не погружаясь в
подкаталоги.
7.6.2. Действия выполняемые командой find(1) с
найденными файлами
Простейшее действие — напечатать имя файла на
STDOUT. Это действие по умолчанию
предпринимается если ничего другого не указано. Оно эквивалентно
указанию опции -print.
-print-
Действие по умолчанию. Напечатать имя файла.
-print0-
Напечатать имя файла. Имена при этом будут разделяться
нулевым символом. Опция сделана для совместной работы с
командой xargs(1).
-ls-
Про каждый файл выводится подробная информация. Так, как
будто к файлам применили команду
ls
-dgils.
-delete
Опция есть только в FreeBSD!
Удалить найденные файлы и директории.
-exec команда [опции [{}]] ;-
Наиболее общий случай. Позволяет применить к найденным
файлам произвольную команду. Опции будут переданы этой
команде. Если в опциях встретится пара скобок
{}, то она будет заменена именем файла (с
путём). Символ ; означает, что в этом
месте закончилась команда и её опции.
-execdir команда [опции [{}]] ;-
То же, что и
-exec, но при выполнении
команды find(1) переходит в каталог,
где находится файл, а {} заменяет на имя
файла без пути.
-ok команда [опции [{}]] ;-
То же, что и
-exec, но перед выполнением
команды find(1) запрашивает
подтверждение у пользователя.
-exec команда [опции [{}]] +
Опция есть только в FreeBSD!
Эквивалентна опции -exec ... ;, но
замещает {} не одним найденным файлом, а
списком файлов. Таким образом, указанная команда
вызывается лишь однажды. Это работает как же, как связка с
командой xargs(1).
7.6.3. Связка с командой xargs
xargs [опции] команда с аргументами
Команда xargs(1) читает список файлов из своего
STDIN и подставляет эти файлы в качестве
аргумента команде указываемой ей в аргументе. Её удобно
применять в связке с find(1). Например, пусть
нам надо узнать сколько строк в каком из журнальных файлов на
нашей системе.
$ find /var/log \! -name *bz2 -type f | xargs wc -l
875 /var/log/auth.log
125 /var/log/cron
270 /var/log/debug.log
.....
Знак \ перед ! мы поставили для того, чтобы sh не
интерпретировал его по-своему. Аналогичного результата мы могли
бы добиться используя опцию -exec.
$ find /var/log \! -name *bz2 -type f -exec wc -l {} \;
875 /var/log/auth.log
125 /var/log/cron
270 /var/log/debug.log
.....
Даже на современной, быстродействующей машине разница в
выполнении этих двух команд видна невооружённым взглядом. Мы
можем её измерить:
$ time find /var/log \! -name *bz2 -type f | xargs wc -l > /dev/null
real 0m0.032s
user 0m0.000s
sys 0m0.024s
$ time find /var/log \! -name *bz2 -type f -exec wc -l {} \; > /dev/null
real 0m0.242s
user 0m0.040s
sys 0m0.191s
Разница составила целый порядок. А ведь здесь ещё мало файлов. В
чём же дело? А дело в том, что find(1) с
опцией -exec для каждого найденного файла
заново вызывает команду wc(1). Вызов команд в
UNIX (и не только в нём) — очень
дорогая процедура. В случае с использованием
xargs(1), мы вызвали wc(1)
только один раз. Подсчёт статистики связанный с чтением и
анализом содержиного файла более прост, чем сам вызов
wc(1).
Ещё очень полезной особенностью xargs(1),
является то, что он может разбирать список файлов с
STDIN, считая символом разделителем не
пробел, а нулевой символ, которого в принципе не может быть в
имени файла. Это может быть очень важно, например, при работе с
разделами Windows или Macintosh.
$ find /mnt/samba ... -print0 | xargs -0 ...
Теперь, какие бы причудливые имена ни встретились нам, даже если
они содержат кавычки, пробелы, символы конца строки, они будут
обработаны корректно.
|  |  | | 7.5. Поиск файлов и бинарников в системе |  | 7.7. Написание несложных Bourne-скриптов |
Главная > Операционные системы > UNIX
|