Главная > Операционные системы > 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
|