- Поиск в Linux с помощью команды find
- Общий синтаксис
- Описание опций
- Примеры использования find
- Поиск файла по имени
- Поиск по дате
- По типу
- Поиск по правам доступа
- Поиск файла по содержимому
- С сортировкой по дате модификации
- Лимит на количество выводимых результатов
- Поиск с действием (exec)
- Чистка по расписанию
- Понимание -regex с GNU find
- Задний план
- Поиск файлов с ls
- Поиск файлов с помощью find
- Вопросов
- Регулярные выражения Linux
- Регулярные выражения Linux
- Примеры использования регулярных выражений
- Выводы
Поиск в Linux с помощью команды find
Утилита find представляет универсальный и функциональный способ для поиска в Linux. Данная статья является шпаргалкой с описанием и примерами ее использования.
Общий синтаксис
— путь к корневому каталогу, откуда начинать поиск. Например, find /home/user — искать в соответствующем каталоге. Для текущего каталога нужно использовать точку «.».
— набор правил, по которым выполнять поиск.
* по умолчанию, поиск рекурсивный. Для поиска в конкретном каталоге можно использовать опцию maxdepth.
Описание опций
Опция | Описание |
---|---|
-name | Поиск по имени. |
-iname | Регистронезависимый поиск по имени. |
-type | |
-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 |
Показать найденное. | |
-print0 | Путь к найденным объектам. |
-exec <> \; | Выполнить команду над найденным. |
-ok | Выдать запрос перед выполнением -exec. |
Также доступны логические операторы:
Оператор | Описание |
---|---|
-a | Логическое И. Объединяем несколько критериев поиска. |
-o | Логическое ИЛИ. Позволяем команде find выполнить поиск на основе одного из критериев поиска. |
-not или ! | Логическое НЕ. Инвертирует критерий поиска. |
Полный набор актуальных опций можно получить командой man find.
Примеры использования find
Поиск файла по имени
1. Простой поиск по имени:
find / -name «file.txt»
* в данном примере будет выполнен поиск файла с именем file.txt по всей файловой системе, начинающейся с корня /.
2. Поиск файла по части имени:
* данной командой будет выполнен поиск всех папок или файлов в корневой директории /, заканчивающихся на .tmp
3. Несколько условий.
а) Логическое И. Например, файлы, которые начинаются на sess_ и заканчиваются на cd:
find . -name «sess_*» -a -name «*cd»
б) Логическое ИЛИ. Например, файлы, которые начинаются на sess_ или заканчиваются на cd:
find . -name «sess_*» -o -name «*cd»
в) Более компактный вид имеют регулярные выражения, например:
find . -regex ‘.*/\(sess_.*cd\)’
* где в первом поиске применяется выражение, аналогичное примеру а), а во втором — б).
4. Найти все файлы, кроме .log:
find . ! -name «*.log»
* в данном примере мы воспользовались логическим оператором !.
Поиск по дате
1. Поиск файлов, которые менялись определенное количество дней назад:
find . -type f -mtime +60
* данная команда найдет файлы, которые менялись более 60 дней назад.
2. Поиск файлов с помощью 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
По типу
Искать в текущей директории и всех ее подпапках только файлы:
* f — искать только файлы.
Поиск по правам доступа
1. Ищем все справами на чтение и запись:
find / -perm 0666
2. Находим файлы, доступ к которым имеет только владелец:
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, добавит к имени дату модификации и отсортирует данные по имени. В итоге получаем, что файлы будут идти в порядке их изменения.
Лимит на количество выводимых результатов
Самый распространенный пример — вывести один файл, который последний раз был модифицирован. Берем пример с сортировкой и добавляем следующее:
find /data -type f -printf ‘%TY-%Tm-%Td %TT %p\n’ | sort -r | head -n 1
Поиск с действием (exec)
1. Найти только файлы, которые начинаются на sess_ и удалить их:
find . -name «sess_*» -type f -print -exec rm <> \;
* -print использовать не обязательно, но он покажет все, что будет удаляться, поэтому данную опцию удобно использовать, когда команда выполняется вручную.
2. Переименовать найденные файлы:
find . -name «sess_*» -type f -exec mv <> new_name \;
find . -name «sess_*» -type f | xargs -I ‘<>‘ mv <> new_name
3. Вывести на экран количество найденных файлов и папок, которые заканчиваются на .tmp:
find . -name «*.tmp» | wc -l
4. Изменить права:
find /home/user/* -type d -exec chmod 2700 <> \;
* в данном примере мы ищем все каталоги (type d) в директории /home/user и ставим для них права 2700.
5. Передать найденные файлы конвееру (pipe):
find /etc -name ‘*.conf’ -follow -type f -exec cat <> \; | grep ‘test’
* в данном примере мы использовали find для поиска строки test в файлах, которые находятся в каталоге /etc, и название которых заканчивается на .conf. Для этого мы передали список найденных файлов команде grep, которая уже и выполнила поиск по содержимому данных файлов.
6. Произвести замену в файлах с помощью команды sed:
find /opt/project -type f -exec sed -i -e «s/test/production/g» <> \;
* находим все файлы в каталоге /opt/project и меняем их содержимое с test на production.
Чистка по расписанию
Команду find удобно использовать для автоматического удаления устаревших файлов.
Открываем на редактирование задания cron:
0 0 * * * /bin/find /tmp -mtime +14 -exec rm <> \;
* в данном примере мы удаляем все файлы и папки из каталога /tmp, которые старше 14 дней. Задание запускается каждый день в 00:00.
* полный путь к исполняемому файлу find смотрим командой which find — в разных UNIX системах он может располагаться в разных местах.
Источник
Понимание -regex с GNU find
Задний план
У меня есть то, что, по моему мнению, должно быть простым. Я хочу найти все файлы с «cisco» в имени и сделать что-то с этими файлами (через xargs ).
Поиск файлов с ls
Прежде чем использовать xargs , первым шагом будет перечисление всех соответствующих файлов. Список файлов легко с ls | grep cisco ls | grep cisco …
Поиск файлов с помощью find
Хотя это, вероятно, не требуется в этом конкретном случае, найти, как правило, считается безопасным при прокладке трубопроводов в xargs . Однако вся логика, кажется, выходит из окна, когда я использую find -regex .
Однако я знаю, что могу найти эти файлы …
Вопросов
Я понимаю, что find -regex должен соответствовать возврату полного пути, но почему не find -regextype grep -regex «.*/cisco*» -print работает выше? Не следует .*/cisco* соответствует пути?
Я знаю, что я мог бы просто использовать find -path «*cisco*» для решения проблемы, но дело в том, чтобы понять, почему использование my -regex неверно.
Поиск с помощью ls : сначала сначала, ls | grep cisco ls | grep cisco немного многословный, поскольку cisco не является регулярным выражением. Пытаться:
Используя find : по тем же линиям, -regex переполняется простым статическим шаблоном. Как насчет:
Кавычки требуются, поэтому glob интерпретируется find , а не оболочкой. Кроме того, -print требуется для многих версий find , но является необязательным (и предикатом по умолчанию) для других (например, GNU find ). Не стесняйтесь добавлять его, если вам это нужно.
Если вам нужно найти «cisco» в полном пути, вы можете попробовать следующее:
что эквивалентно find | fgrep cisco find | fgrep cisco .
Использование find с регулярными выражениями : давайте сделаем это в любом случае, так как это то, что вы хотите. Бесстыдное копирование с GNU find manpage:
Это означает, что ваше регулярное выражение завернуто в невидимый ^. $ , поэтому он должен соответствовать каждому символу в полном пути файла. Итак, как сказал nwildner и otokan в комментариях, вы должны использовать что-то вроде:
И вам даже не нужен -regextype для чего-то такого простого.
Причина, по которой find -regex «.*/cisco*» не будет соответствовать никаким путям, например ./cisco-eem-tcl.rst или ./cisco_autonomous_to_lwap.rst выглядит следующим образом:
- .* соответствует чему угодно – любому персонажу, ноль или более раз
- / соответствует одной косой чертой – пока что так хорошо
- cisco* соответствует cisc , за которым следует любое количество o .
Помните, что оператор asterix * сдерживает повторение предыдущего элемента, который в этом случае равен o . Это означает, что мы не имеем ничего общего с этим последним компонентом шаблона, потому что это будет нечто вроде cisc , cisco , ciscoo , ciscooo … ad infinitum.
Если вам нужно выразить, что все может следовать за словом cisco , тогда используйте .* После этого:
Возможно, вам хотелось бы немного ограничивать результаты поиска, сопоставляя только rst файлы:
Тем не менее, выполнение простого совпадения в компоненте имени файла пути, таком как это, не требует выразительной мощности регулярных выражений, поэтому вы можете просто отлично использовать только -name с помощью glob для получения того же соответствия:
и для обработки этих совпадений с помощью xargs вы сделали бы что-то вроде этого:
Вы всегда должны помнить, что регулярные выражения и глобусы – это разные вещи синтаксически и семантически. Посмотрите, как man find и читают о параметрах -name и -regex , чтобы узнать больше.
Источник
Регулярные выражения Linux
Регулярные выражения — это очень мощный инструмент для поиска текста по шаблону, обработки и изменения строк, который можно применять для решения множества задач. Вот основные из них:
- Проверка ввода текста;
- Поиск и замена текста в файле;
- Пакетное переименование файлов;
- Взаимодействие с сервисами, таким как Apache;
- Проверка строки на соответствие шаблону.
Это далеко не полный список, регулярные выражения позволяют делать намного больше. Но для новых пользователей они могут показаться слишком сложными, поскольку для их формирования используется специальный язык. Но учитывая предоставляемые возможности, регулярные выражения Linux должен знать и уметь использовать каждый системный администратор.
В этой статье мы рассмотрим регулярные выражения bash для начинающих, чтобы вы смогли разобраться со всеми возможностями этого инструмента.
Регулярные выражения Linux
В регулярных выражениях могут использоваться два типа символов:
Обычные символы — это буквы, цифры и знаки препинания, из которых состоят любые строки. Все тексты состоят из букв и вы можете использовать их в регулярных выражениях для поиска нужной позиции в тексте.
Метасимволы — это кое-что другое, именно они дают силу регулярным выражениям. С помощью метасимволов вы можете сделать намного больше чем поиск одного символа. Вы можете искать комбинации символов, использовать динамическое их количество и выбирать диапазоны. Все спецсимволы можно разделить на два типа, это символы замены, которые заменяют собой обычные символы, или операторы, которые указывают сколько раз может повторяться символ. Синтаксис регулярного выражения будет выглядеть таким образом:
обычный_символ спецсимвол_оператор
спецсимвол_замены спецсимвол_оператор
Если оператор не указать, то будет считаться, что символ обязательно должен встретится в строке один раз. Таких конструкций может быть много. Вот основные метасимволы, которые используют регулярные выражения bash:
- \ — с обратной косой черты начинаются буквенные спецсимволы, а также он используется если нужно использовать спецсимвол в виде какого-либо знака препинания;
- ^ — указывает на начало строки;
- $ — указывает на конец строки;
- * — указывает, что предыдущий символ может повторяться 0 или больше раз;
- + — указывает, что предыдущий символ должен повторится больше один или больше раз;
- ? — предыдущий символ может встречаться ноль или один раз;
- — указывает сколько раз (n) нужно повторить предыдущий символ;
- — предыдущий символ может повторяться от N до n раз;
- . — любой символ кроме перевода строки;
- [az] — любой символ, указанный в скобках;
- х|у — символ x или символ y;
- [^az] — любой символ, кроме тех, что указаны в скобках;
- [a-z] — любой символ из указанного диапазона;
- [^a-z] — любой символ, которого нет в диапазоне;
- \b — обозначает границу слова с пробелом;
- \B — обозначает что символ должен быть внутри слова, например, ux совпадет с uxb или tuxedo, но не совпадет с Linux;
- \d — означает, что символ — цифра;
- \D — нецифровой символ;
- \n — символ перевода строки;
- \s — один из символов пробела, пробел, табуляция и так далее;
- \S — любой символ кроме пробела;
- \t — символ табуляции;
- \v — символ вертикальной табуляции;
- \w — любой буквенный символ, включая подчеркивание;
- \W — любой буквенный символ, кроме подчеркивания;
- \uXXX — символ Unicdoe.
Важно отметить, что перед буквенными спецсимволами нужно использовать косую черту, чтобы указать, что дальше идет спецсимвол. Правильно и обратное, если вы хотите использовать спецсимвол, который применяется без косой черты в качестве обычного символа, то вам придется добавить косую черту.
Например, вы хотите найти в тексте строку 1+ 2=3. Если вы используете эту строку в качестве регулярного выражения, то ничего не найдете, потому что система интерпретирует плюс как спецсимвол, который сообщает, что предыдущая единица должна повториться один или больше раз. Поэтому его нужно экранировать: 1 \+ 2 = 3. Без экранирования наше регулярное выражение соответствовало бы только строке 11=3 или 111=3 и так далее. Перед равно черту ставить не нужно, потому что это не спецсимвол.
Примеры использования регулярных выражений
Теперь, когда мы рассмотрели основы и вы знаете как все работает, осталось закрепить полученные знания про регулярные выражения linux grep на практике. Два очень полезные спецсимвола — это ^ и $, которые обозначают начало и конец строки. Например, мы хотим получить всех пользователей, зарегистрированных в нашей системе, имя которых начинается на s. Тогда можно применить регулярное выражение «^s». Вы можете использовать команду egrep:
egrep «^s» /etc/passwd
Если мы хотим отбирать строки по последнему символу в строке, что для этого можно использовать $. Например, выберем всех системных пользователей, без оболочки, записи о таких пользователях заканчиваются на false:
egrep «false$» /etc/passwd
Чтобы вывести имена пользователей, которые начинаются на s или d используйте такое выражение:
egrep «^[sd]» /etc/passwd
Такой же результат можно получить, использовав символ «|». Первый вариант более пригоден для диапазонов, а второй чаще применяется для обычных или/или:
egrep «^[s|d]» /etc/passwd
Теперь давайте выберем всех пользователей, длина имени которых составляет не три символа. Имя пользователя завершается двоеточием. Мы можем сказать, что оно может содержать любой буквенный символ, который должен быть повторен три раза, перед двоеточием:
egrep «^\w<3>:» /etc/passwd
Выводы
В этой статье мы рассмотрели регулярные выражения Linux, но это были только самые основы. Если копнуть чуть глубже, вы найдете что с помощью этого инструмента можно делать намного больше интересных вещей. Время, потраченное на освоение регулярных выражений, однозначно будет стоить того.
На завершение лекция от Яндекса про регулярные выражения:
Источник