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

Основными программами для этих задач являются find и xargs.

Некоторые примеры на этой странице используют возможности, характерные для GNU-версий этих программ.

1.1 Область применения

Для краткости, словом файл ниже будем обозначать любой файл в файловой системе:

  • обычный файл: текст, картинка, видео и пр.,
  • каталог (директория),
  • символическую ссылку ,
  • любой другой файл, имеющий указание в каком-то каталоге.

Запись в каталоге (директории) также называется именем файла.

Разные примеры того, что ниже называется путём файла:

  parser.c
  README
  ./budget/may-94.sc
  fred/.cshrc
  /usr/local/include/termcap.h

Дерево каталогов - это каталог и содержащиеся в нем файлы, все его подкаталоги и содержащиеся в них файлы и т.д. его подкаталоги и содержащиеся в них файлы и т.д.

Один регулярный файл без каталогов, в целом, тоже можно считать деревом (но маленьким, из одной вершины).


С помощью find можно найти в одном или нескольких деревьях каталогов файлы, которые:

  • имеют имена, содержащие определенный текст или соответствующие определенному шаблону;
  • являются ссылками на определенные файлы;
  • использовались в последний раз в течение определенного периода времени;
  • находятся в определенном диапазоне размеров;
  • имеют определенный тип (обычный файл, каталог, символическая ссылка и т.д.);
  • принадлежат определенному пользователю или группе;
  • имеют определенные разрешения доступа или биты специального режима;
  • содержат текст, соответствующий определенному шаблону;
  • находятся на определенной глубине в дереве каталогов;
  • или некоторые комбинации вышеперечисленного.

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

Действия, которые можно совершить с найденными файлами, включают следующий список (хотя и не ограничиваются на нём):

  • просмотр или редактирование
  • сохранить в архиве
  • удалить или переименовать
  • изменить права доступа
  • классифицировать по группам

1.2 Быстрый старт

Обзор

find [ФАЙЛ...] [ВЫРАЖЕНИЕ] 

Команда find ищет файлы в дереве каталогов ФАЙЛ, для каждого файла вычисляет ВЫРАЖЕНИЕ и, если оно истинно, то (по умолчанию) выводит имя файла.

В выражении ВЫРАЖЕНИЕ обычно указаны какие-то критерии поиска.


Поиск файлов в /usr/src с расширением .c, размером более 100 Кб:

find /usr/src -name '*.c' -size +100k -print

Обратите внимание, что паттерн *.c заключён в кавычки ('*.c'), чтобы shell не интерпретировал его и передал в find без изменений.

Вывод имени — не единственное, что можно делать с найденными файлами, см. Выполнение команд

2 Выражения

2.1 Выражения ‘find’

Выражение состоит из одного или нескольких “атомов”.

Атомы — это аргументы и флаги командной строки; иногда один атом может состоять из нескольких аргументов: например, когда у флага есть аргумент: -printf '%f'.

Атомы можно разбить на четыре категории:

Параметр

влияет на общую работу, а не на обработку отдельного файла;

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

Исключения: -daystart и -follow, влияющие по-разному в зависимости от места в командной строке. Рекомендуется размещать их в начале.

Тест

возвращает true или false, основываясь на атрибутах файла;

Действие

вызывает побочные эффекты и возвращает истину или ложь;

Композиция

атомы, которые как-то объединяют другие атомы, влияя на порядок их вычисления и определяя вычислятся ли они вообще.

Можно опустить оператор между двумя аргументами; по умолчанию используется -and. См. 2.12 Комбинирование аргументов с операторами

Действие -print выполняется для всех файлов, для которых ВЫРАЖЕНИЕ истинно (*см. Печать имени файла::). ~Исключение: это правило может не работать, если есть флаги -prune или -quit.

Действия, отключающие -print по умолчанию: -delete, -exec, -execdir, -ok, -okdir, -fls, -fprint, -fprintf, -ls, -print, -printf.


Многие флаги требуют аргументов, следующих за ними в командной строке find.

Аргументы могут быть именами файлов, шаблонами, строками или числами.

Числовые аргументы могут быть указаны как:

Аргумент:

+N 

для чисел больше N,

Аргумент:

-N 

для чисел меньше N,

Аргумент:

N 

2.2 Начальные точки

GNU find начинает поиск в указанных каталогах, применяя заданное выражение к каждому найденному файлу.

Процесс продолжается до тех пор, пока не будет определён результат выражения - ложь для “and” или истина для “or”.

После этого find переходит к следующему файлу.

2.3 Поиск по имени файла

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

2.3.1 Поиск по имени

Поиск по имени файла, не учитывая путь файлу.

Тест

-name шаблон

Проверяет, соответствует ли имя файла шаблону шаблон. Учитывает регистр.

Тест

-iname шаблон

То же, что и -name, но без учёта регистра.

2.3.2 Поиск по полному пути

Тест

-path шаблон
-wholename шаблон

Сравнивает весь путь файла с шаблоном шаблон.

Тест

-ipath шаблон
-iwholename шаблон

Версии -path и -wholename, не учитывающие регистр.

2.3.3 Шаблоны

В find используются специальные символы и подстановочные знаки для сопоставления шаблонов имен.

Специальные символы:

  • * соответствует любому количеству символов.
  • ? соответствует одному символу.
  • [STRING] соответствует одному символу из строки STRING, которая может включать диапазоны.
  • \ убирает специальное значение следующего за ним символа.

Для детальной информации об этих опциях см. info findutils.


Шаблон shell - это строка, содержащая специальные символы, известные как глобы.

Шаблоны с глобами следует заключать в кавычки, чтобы оболочка не интерпретировала их самостоятельно.

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

2.4 Ссылки

Файлы могут быть связаны двумя способами: символическими и жесткими ссылками.

2.4.1 Символические ссылки

Символические ссылки - это файлы, содержащие путь к другому файлу.

Обработка символических ссылок в find:

  • Разыменование ссылок: find проверяет файл, на который указывает ссылка.
  • Проверка самой ссылки: find может анализировать саму ссылку без разыменования.

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

  • Используйте -L для исключения ссылок и анализа связанных файлов. -P устанавливает поведение по умолчанию.
  • -H частично разграничивает символические ссылки, указанные в командной строке.

Тест

-lname шаблон

Истина, если символическая ссылка соответствует шаблону шаблон. -ilname игнорирует регистр.

2.4.2 Жесткие ссылки

Жесткие ссылки - это разные имена файла, ссылающиеся на один и тот же инод.

Тест

-samefile ИМЯ

Истина, если файл является жесткой ссылкой на тот же инод, что и ИМЯ.

Тесты для анализа количества жестких ссылок:

-inum n
-links n
-links +n
-links -n

Проверяют номер инода и количество жестких ссылок.

2.5 Время

Каждый файл имеет три временные метки: доступ, изменение и модификация. Некоторые системы также предоставляют метку создания файла.

2.5.1 Диапазоны времени

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

Тесты времени:

-atime n
-ctime n
-mtime n
-amin n
-cmin n
-mmin n
-daystart

Проверяют время доступа, изменения и модификации файла.

2.5.2 Сравнение временных меток

Тесты для сравнения временных меток:

-newerXY ссылка
-anewer ссылка
-cnewer ссылка
-newer ссылка
-used n

Сравнивают временные метки текущего файла с файлом-ссылкой.

Для более подробной информации о работе с временными метками и ссылками в find обратитесь к info findutils.

2.6 Размер

Тест

-size n[bckwMG]

Истина, если файл занимает N единиц пространства с округлением в большую сторону. Единицы могут быть указаны с помощью суффиксов типа b, c, w, k, M, G.

Тест

-empty

Истина, если файл пуст и является либо обычным файлом, либо каталогом.

2.7 Type

Тест

-type c

Истина, если файл имеет тип C (‘b’, ‘c’, ‘d’, ‘p’, ‘f’, ‘l’, ‘s’, ‘D’).

Тест

-xtype c

Ведет себя так же, как и -type, если только файл не является символической ссылкой. Проверяет тип файла, который не проверяет -type.

2.8 Владелец файла

find позволяет искать файлы на основе информации о владельце и группе.

Тесты для определения владельца файла:

-user имя_пользователя
-group имя_группы
-uid n
-gid n

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

Тесты для поиска файлов без владельца или группы:

-nouser
-nogroup

Истина, если файл не имеет владельца или группы, соответствующих существующим пользователям или группам.

2.9 Биты прав на файл

find также позволяет искать файлы на основе разрешений на них.

Тесты для проверки разрешений файла:

-readable
-writable
-executable

Проверяют, может ли вызывающий пользователь читать, писать или выполнять файл.

Тест

-perm режим

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

2.10 Поиск по содержимому файла

Для поиска файлов по содержимому используйте комбинацию grep, find и xargs. Например, чтобы найти исходные файлы C в текущем каталоге, содержащие строку ‘thing’:

grep -l thing *.[ch]

Для поиска в подкаталогах:

find . -name '*.[ch]' | xargs grep -l thing

Опция -l в grep выводит только имена файлов, содержащих строку. Строка ‘thing’ является регулярным выражением и может содержать метасимволы.

Для улучшения метода используйте -print0 в find и -0 в xargs для корректной обработки имен файлов с пробелами:

find . -name '*.[ch]' -print0 | xargs -r -0 grep -l thing

Для детального описания поиска файлов по содержимому см. руководство grep.

2.11 Обработка каталогов

Управление поиском в каталогах с find:

Параметр

-maxdepth уровни

Ограничивает поиск до указанного количества уровней каталогов ниже аргументов командной строки. -maxdepth 0 применяет тесты и действия только к аргументам командной строки.

Примеры:

mkdir -p dir/d1/d2/d3/d4/d5/d6
find dir -maxdepth 1

Вывод:

dir
dir/d1
find dir -mindepth 5

Вывод:

dir/d1/d2/d3/d4/d5
dir/d1/d2/d3/d4/d5/d6
find dir -mindepth 2 -maxdepth 4

Вывод:

dir/d1/d2
dir/d1/d2/d3
dir/d1/d2/d3/d4

Параметр

-mindepth уровни

Параметр

-depth

Параметр

-d

Действие:

-prune

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

Пример:

find . -wholename './src/emacs' -prune -o -print

Действие

-quit

Немедленный выход из find. Отличается от -prune тем, что -quit заставляет find остановиться сразу.

Пример:

find / -name needle -print -quit

2.12 Операторы для композиции команд

Операторы позволяют составные выражения из тестов и действий.

Операторы располагаются в порядке убывания старшинства:

Композиция

( EXPR )

Принудительный приоритет. Истинно, если EXPR истинен.

Композиция

! EXPR
-not EXPR

Истинно, если EXPR ложно. В некоторых оболочках необходимо защитить ’!’ от интерпретации оболочкой, заключив его в кавычки.

Композиция

EXPR1 EXPR2
EXPR1 -a EXPR2
EXPR1 -and EXPR2

И; EXPR2 не вычисляется, если EXPR1 ложен.

Композиция

EXPR1 -o EXPR2
EXPR1 -or EXPR2

Или; EXPR2 не вычисляется, если EXPR1 истинен.

Композиция

EXPR1 , EXPR2

Список; всегда вычисляются оба EXPR1 и EXPR2.

Истинно, если EXPR2 истинно. Значение EXPR1 отбрасывается.

Этот оператор позволяет Вам выполнять несколько независимых операций в одном обходе, не завися от того, были ли успешны другие операции.

Две операции EXPR1 и EXPR2 не всегда полностью независимы, поскольку EXPR1 может иметь побочные эффекты, такие как касание или удаление файлов, или может использовать -prune, что также повлияет на EXPR2.

find ищет в дереве каталогов, уходящем корнями в каждое имя файла, выполняя выражение слева направо, в соответствии с правилами старшинства, пока результат не будет известен (левая сторона ложна для ‘-and’, истинна для ‘-or’), и тогда find переходит к следующему имени файла.

Есть еще два теста, которые могут быть полезны в сложных выражениях:

Тест

-true

Всегда верно.

Тест

-false

Всегда ложно.

3 Действия

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

Можно выводить информацию на стандартный вывод или в файл, а также выполнять команды с именами файлов в качестве аргументов.

3.1 Печать имени файла

Действие:

-print

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

Действие

-fprint файл

Выводит полное имя файла в указанный файл. Если файл не существует, он будет создан.

3.2 Печать информации о файле

Действие

-ls

Выводит информацию о файле в сокращенном формате, аналогичном ls -dils.

Действие

-fls файл

Аналогично -ls, но записывает информацию в указанный файл.

Действие

-printf формат

Выводит информацию о файле в заданном формате, интерпретируя эскейпы и директивы. Не добавляет новую строку автоматически.

Примеры использования -printf для настройки формата вывода:

  • Вывод имени файла, его размера и даты последнего изменения:

    find /path/to/search -printf "%f\t%s bytes\t%T+\n"
  • Вывод имени файла, владельца и группы:

    find /path/to/search -printf "File: %f\tOwner: %u\tGroup: %g\n"
  • Вывод имени файла и его типа:

    find /path/to/search -printf "File: %f\tType: %y\n"

Действие

-fprintf файл формат

Аналогично -printf, но записывает в указанный файл.

3.3 Выполнеие команд

Вы можете использовать список имен файлов, созданный командой ‘find’, в качестве аргументов к другим командам.

Таким образом, Вы можете выполнять произвольные действия над файлами.

3.3.1 Одиночный файл

Вот как выполнить команду для одного файла за раз.

Действие

-execdir command ;

Выполнение КОМАНДЫ; true, если КОМАНДА возвращает ноль. find воспринимает все аргументы после -execdir как часть команды, пока не будет достигнут аргумент, состоящий из ;. Она заменяет строку {} на текущее имя файла, обрабатываемое везде, где оно встречается в команде. Обе эти конструкции должны быть экранированы (с помощью \) или заключены в кавычки, чтобы защитить их от расширения оболочкой. Команда выполняется в директории, которую find искал в момент выполнения действия (то есть, {} расширится до файла в локальной директории).

Например, чтобы сравнить каждый заголовочный файл C в текущем каталоге или под ним с файлом /tmp/master:

find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'

Предупреждение!

Если Вы используете -execdir, Вы должны убедиться, что переменная PATH содержит только абсолютные пути каталогов.

Наличие пустого элемента в PATH или явное включение . (или любого другого неабсолютного имени) небезопасно.

GNU find откажется запускаться, если Вы используете -execdir и он считает, что Ваша настройка PATH небезопасна.

3.3.2 Обработка нескольких файлов

Основные принципы

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

Это экономит время, необходимое для запуска команды каждый раз.

С помощью -execdir и -exec можно исполнять команды, содержащие множество файлов в качестве аргументов.

Использование -execdir и -exec

Действие

-execdir command {} +

Это действие работает аналогично -execdir command ;, но {} в конце команды раскрывается до списка подходящих файлов. Раскрытие выполняется таким образом, чтобы не превысить максимальную длину командной строки. В команде допускается только один {}, и он должен находиться в конце, непосредственно перед +.

Действие

-exec command {} +

Этот вариант, определенный POSIX, работает похожим образом, но выполняет команду в каталоге, из которого был вызван find. {} расширяется до относительного пути, начинающегося с имени одного из начальных каталогов.

Обработка ошибок и выход из find

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

Решение проблем с расположением аргументов

Иногда требуется, чтобы имена файлов находились не в конце командной строки. Решение этой проблемы заключается в использовании команды sh -c:

find startpoint -tests ... -exec sh -c 'scp "$@" remote:/dest' {} +

В этом примере "$@" в команде scp раскрывается до списка имен файлов.

3.3.2.1 Небезопасная обработка имен файлов

Использование xargs по умолчанию может быть небезопасным из-за специальных символов в именах файлов. Например, команда из cron может быть использована для удаления любого файла:

find / -name '#*' -atime +7 -print | xargs rm

Это может привести к удалению критических системных файлов.

3.3.2.2 Безопасная работа с именами файлов

Для безопасной работы с именами файлов используйте опции -0 или --null с xargs, tar, cpio или perl.

Например:

find / -name xyzzy -print0 > list
xargs -0 -a list munge

или

find / -name xyzzy -print0 | xargs -0 munge

3.3.2.3 Необычные символы в именах файлов

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

Ссылки по теме

3.3.3 Команды с подтверждением пользователем

Для команд, требующих подтверждения пользователя перед выполнением, find предлагает опции -okdir и -ok.

Действие с подтверждением пользователя

-okdir команда

Аналогично -execdir, но сначала запрашивает подтверждение пользователя. Если пользователь отказывается, возвращается false.

-ok command ;

Менее безопасный вариант, предусмотренный POSIX. Он выполняет команду в директории, из которой была вызвана find.