Поиск в Linux с помощью команды find
Общий синтаксис
find <где искать> <опции>
<где искать> — путь к корневому каталогу, откуда начинать поиск. Например, find /home/user — искать в соответствующем каталоге. Для текущего каталога нужно использовать точку «.».
<опции> — набор правил, по которым выполнять поиск.
по умолчанию, поиск рекурсивный. Для поиска в конкретном каталоге можно использовать опциюmaxdepth**.*
Описание опций
| Опция | Описание |
|---|---|
| -name | Поиск по имени. |
| -iname | Регистронезависимый поиск по имени. |
| -type | Тип объекта поиска. Возможные варианты: |
-
f — файл;
-
d — каталог;
-
l — ссылка;
-
p — pipe;
-
s — сокет. | | -size | Размер объекта. Задается в блоках по 512 байт или просто в байтах (с символом «c»). | | -mtime | Время изменения файла. Указывается в днях. | | -mmin | Время изменения в минутах. | | -atime | Время последнего обращения к объекту в днях. | | -amin | Время последнего обращения в минутах. | | -ctime | Последнее изменение владельца или прав на объект в днях. | | -cmin | Последнее изменение владельца или прав в минутах. | | -user | Поиск по владельцу. | | -group | По группе. | | -perm | С определенными правами доступа. | | -depth | Поиск должен начаться не с корня, а с самого глубоко вложенного каталога. | | -maxdepth | Максимальная глубина поиска по каталогам. -maxdepth 0 — поиск только в текущем каталоге. По умолчанию, поиск рекурсивный. | | -prune | Исключение перечисленных каталогов. | | -mount | Не переходить в другие файловые системы. | | -regex | По имени с регулярным выражением. | | -regextype | Тип регулярного выражения. | | -L или -follow | Показывает содержимое символьных ссылок (симлинк). | | -empty | Искать пустые каталоги. | | -delete | Удалить найденное. | | -ls | Вывод как ls -dgils | | -print | Показать найденное. | | -print0 | Путь к найденным объектам. | | -exec {} ; | Выполнить команду над найденным. | | -ok | Выдать запрос перед выполнением -exec. |
Также доступны логические операторы:
| Оператор | Описание |
|---|---|
| -a | Логическое И. Объединяем несколько критериев поиска. |
| -o | Логическое ИЛИ. Позволяем команде find выполнить поиск на основе одного из критериев поиска. |
| -not или ! | Логическое НЕ. Инвертирует критерий поиска. |
Полный набор актуальных опций можно получить командой man find.
Примеры использования find
Поиск файла по имени
- Простой поиск по имени:
find / -name “file.txt”
в данном примере будет выполнен поиск файла с именемfile.txtпо всей файловой системе, начинающейся с корня/**.*
- Поиск файла по части имени:
find / -name “*.tmp”
данной командой будет выполнен поиск всех папок или файлов в корневой директории/,заканчивающихся на.tmp***
- Несколько условий.
а) Логическое И. Например, файлы, которые начинаются на sess_и заканчиваются наcd:
find . -name “sess_*” -a -name “*cd”
б) Логическое ИЛИ. Например, файлы, которые начинаются на sess_или заканчиваются наcd:
find . -name “sess_*” -o -name “*cd”
в) Более компактный вид имеют регулярные выражения, например:
find . -regex ’.*/(sess_.*cd)’
find . -regex ’./(sess_.|.*cd)’
** где в первом поиске применяется выражение, аналогичное примеру а), а во втором — б).*
Будте аккуратнее при использовании условий, так как они отделяют одну часть опций, от другой. Например:
find ./ -name 1 -o -name 2 -type f
… будет искать либо все с именем 1, либо только файлы с именем 2 (опция -type fнаходится после**-o** справа). Если нужны файлы с именем 1 или 2, то используем скобки:
find ./ ( -name 1 -o -name 2 ) -type f
** Обратите внимание, что скобки должны быть заэкранированы, а также должен быть пробельный отступ внутри скобок.*
- Найти все файлы, кроме .log:
find . ! -name “*.log”
в данном примере мы воспользовались логическим оператором!**.*
Поиск по дате
- Поиск файлов, которые менялись определенное количество дней назад:
find . -type f -mtime +60
данная команда найдет файлы, которые менялись более60** дней назад.*
Или в промужутке:
find . -mmin -20 -mmin +10 -type f
найти все файлы, которые менялись более10минут, но не более20**-и.*
- Поиск файлов с помощью newer. Данная опция доступна с версии 4.3.3 (посмотреть можно командойfind —version).
а) дате изменения:
find . -type f -newermt “2019-11-02 00:00”
** покажет все файлы, которые менялись, начиная с 02.11.2019 00:00.*
find . -type f -newermt 2019-10-31 ! -newermt 2019-11-02
** найдет все файлы, которые менялись в промежутке между 31.10.2019 и 01.11.2019 (включительно).*
б) дате обращения:
find . -type f -newerat 2019-10-08
** все файлы, к которым обращались с 08.10.2019.*
find . -type f -newerat 2019-10-01 ! -newerat 2019-11-01
** все файлы, к которым обращались в октябре.*
в) дате создания:
find . -type f -newerct 2019-09-07
** все файлы, созданные с 07 сентября 2019 года.*
find . -type f -newerct 2019-09-07 ! -newerct “2019-09-09 07:50:00”
- файлы, созданные с 07.09.2019 00:00:00 по 09.09.2019 07:50
Или можно найти все файлы, созданные за сегодняшний день:
find ./ -newerct ‘yesterday’
По типу
- Искать в текущей директории и всех ее подпапках только файлы:
find . -type f
** f — искать только файлы.*
- Найти только директории:
find . -type d
** d — искать только папки.*
- Найти исполняемые (бинарные) файлы.
У find нет опции для поиска бинарных файлов, но мы можем передать результат поиска команде grep -ILс помощьюexec (подробнее рассмотрен ниже):
find / -name openssl -type f -exec grep -IL . ”{}” ;
в данном примере мы найдем в системе все файлы с именемopenssl**, которые являются исполняемыми.*
Поиск по правам доступа
- Ищем все справами на чтение и запись:
find / -perm 0666
- Находим файлы, доступ к которым имеет только владелец:
find / -perm 0600
Поиск файла по содержимому
find / -type f -exec grep -i -H “content” {} ;
в данном примере выполнен рекурсивный поиск всех файлов в директории/и выведен список тех, в которых содержится строкаcontent**.*
С сортировкой по дате модификации
find /data -type f -printf ‘%TY-%Tm-%Td %TT %p\n’ | sort -r
команда найдет все файлы в каталоге/data**, добавит к имени дату модификации и отсортирует данные по имени. В итоге получаем, что файлы будут идти в порядке их изменения.*
Или попроще с использованием ls:
find /data -type f | ls -1t
или в обратном порядке:
find /data -type f | ls -1tr
Лимит на количество выводимых результатов
Самый распространенный пример — вывести один файл, который последний раз был модифицирован. Берем пример с сортировкой и добавляем следующее:
find /data -type f -printf ‘%TY-%Tm-%Td %TT %p\n’ | sort -r | head -n 1
Поиск с действием (exec)
- Найти только файлы, которые начинаются на sess_ и удалить их:
find . -name “sess_*” -type f -print -exec rm {} ;
** -print использовать не обязательно, но он покажет все, что будет удаляться, поэтому данную опцию удобно использовать, когда команда выполняется вручную.*
- Переименовать найденные файлы:
find . -name “sess_*” -type f -exec mv {} new_name ;
или:
find . -name “sess_*” -type f | xargs -I ’{}’ mv {} new_name
- Переместить найденные файлы:
find . -name “sess_*” -type f -exec mv {} /new/path/ ;
в данном примере мы переместим все найденные файлы в каталог/new/path/**.*
- Вывести на экран количество найденных файлов и папок, которые заканчиваются на .tmp:
find . -name “*.tmp” | wc -l
- Изменить права.
Рассмотрим пример, как найти все папки и задать им определенные права:
find /home/user/* -type d -exec chmod 2700 {} ;
в данном примере мы ищем все каталоги (type d) в директории/home/userи ставим для них права2700**.*
Или так можно изменить права для всех файлов и каталогов:
find ./ -type f -exec chmod 0644 {} ;
в данном примере мы ищем все файлы (type f) в текущей директории./и ставим для них права0644**.*
find ./ -type d -exec chmod 0755 {} ;
в данном примере мы ищем все папки (type d) в текущей директории./и ставим для них права0755**.*
- Передать найденные файлы конвееру (pipe):
find /etc -name ‘*.conf’ -follow -type f -exec cat {} ; | grep ‘test’
в данном примере мы использовали find для поиска строкиtestв файлах, которые находятся в каталоге/etc**, и название которых заканчивается на**.conf**. Для этого мы передали список найденных файлов командеgrep, которая уже и выполнила поиск по содержимому данных файлов.*
- Произвести замену в файлах с помощью команды sed:
find /opt/project -type f -exec sed -i -e “s/test/production/g” {} ;
находим все файлы в каталоге/opt/projectи меняем их содержимое сtestнаproduction**.*
- Выполнить несколько команд можно с помощью нескольких вызовов exec:
find ./ -type d -exec chmod 0755 {} ; -exec chown dmosk {} ;
в итоге, первая команда будет назначать права0755**, а вторая — задавать владельцаdmosk.*
Чистка по расписанию
Команду find удобно использовать для автоматического удаления устаревших файлов.
Открываем на редактирование задания cron:
crontab -e
И добавляем:
0 0 * * * /bin/find /tmp -mtime +14 -exec rm {} ;
в данном примере мы удаляем все файлы и папки из каталога/tmp,которые старше14дней. Задание запускается каждый день в00:00**.
- полный путь к исполняемому файлу find смотрим командой which find — в разных UNIX системах он может располагаться в разных местах.*
Поиск файлов с помощью bat в любом месте
Чтобы найти все файлы в любом месте внутри, /path/to/folder имена которых содержат bat, вы можете использовать:
find /path/to/folder -name '*bat*'
Я заключил в кавычки шаблон поиска *bat* потому, что, если бы кавычки были опущены и файлы, соответствующие *bat* в текущем каталоге, были бы перечислены, оболочка превратила бы *bat* в их список и передала его в find. Тогда find не работало бы должным образом. (\*bat\* и "*bat*" тоже работают.)
Чтобы выполнить поиск в папке, в которой вы находитесь в данный момент (например, в той, в которую вы cd перешли), используйте ., как обычно:
find . -name '*bat*'
Чтобы выполнить поиск по всему компьютеру, используйте /. Чтобы выполнить поиск по домашнему каталогу, используйте ~ или полное имя вашего домашнего каталога. (Оболочка расшифровывает ~ до полного пути к вашему домашнему каталогу.)
Расширение или сужение вашего поиска В зависимости от названия
Если вы хотите выполнять поиск без учёта регистра, чтобы файлы, содержащие BAT, bAt, и так далее, совпадали, используйте тест -iname вместо теста -name.
find /path/to/folder -iname '*bat*'
Я заметил, что все ваши файлы заканчиваются на .c. Если вы хотите найти только такие файлы, используйте:
find /path/to/folder -name '*bat*.c'
Я заметил, что во всех ваших именах файлов bat находится либо в самом начале, либо в самом конце части, предшествующей суффиксу .c. Если вы хотите избежать совпадения с файлами, подобными embattled.c, вы можете использовать:
find /path/to/folder -name '*bat.c' -o -name 'bat*.c'
-o является оператором или.
Только Совпадающие файлы
Чтобы найти только обычные файлы, а не папки, символические ссылки и специальные узлы устройств, вы можете использовать -type f. Это часто рекомендуется и иногда вполне уместно… но часто это не то, что вам нужно, особенно если вы запускаете find для самостоятельного изучения результатов. Если бы у вас была символическая ссылка, соответствующая вашему запросу, разве вы не хотели бы узнать о ней?
Если вы хотите найти как обычные файлы, так и символические ссылки, вы можете использовать:
find /path/to/folder -name '*bat*' \( -type f -o -type l \)
Для этого используется оператор -o и скобки для группировки (которые должны быть заключены в кавычки, чтобы оболочка не обрабатывала их особым образом; в противном случае вы получите синтаксическую ошибку).
Но предположим, что вы хотите видеть только символические ссылки, которые в конечном итоге указывают на обычный файл (а не на символические ссылки на каталоги, узлы устройств и т. д.). На самом деле это ещё проще: используйте -xtype вместо -type. Если вы не запускаете find с флагом -L, -xtype для символической ссылки проверяет тип файла, на который указывает ссылка.
find /path/to/folder -name '*bat*' -xtype f
Если у вас есть символическая ссылка на другую символическую ссылку на файл, -xtype f будет соответствовать ей, даже если её прямой целью является другая символическая ссылка, а не обычный файл. Это почти всегда то, что вам нужно.
Часто люди думают, что хотят -type f, но на самом деле они хотят -xtype f.
Получение подробных выходных данных
findЕсли вы не укажете действие по умолчанию, оно будет равно -print. Все приведённые выше команды эквивалентны самим себе с добавленным в конце -print
find часто используется для запуска команд на основе найденных файлов — часто это команды, которые вносят изменения. Но есть и другие действия, целью которых является отображение результатов, помимо -print. Особый интерес представляет -ls:
find /path/to/folder -name '*bat*' -ls
Это даёт подробную информацию о каждом файле в формате с несколькими столбцами, похожем на (хотя и не совсем таком же, как) то, что вы увидите при запуске ls *file*.
find /home/bitrix/wwwhttps://eu-digital.ru/upload/ -type d -name “1c-catalog” -delete
Удалить рекурсивно все каталоги, подкаталоги и файлы.
find /home/bitrix/www/upload -type d -name “1c_catalog” -exec rm -rf {} +
Ищете надежного партнера по веб-разработке и автоматизации? Мы помогаем бизнесу расти с помощью современных технологий, автоматизации процессов и экспертного SEO. Свяжитесь с нами, чтобы обсудить вашу задачу.