Всем доброго времени суток и всяческих таких прочих разностей.
Давно что-то я ничего не писал на серверную тему в блоговую часть сайта. Сегодня немного привычных и унылых, для многих опытных человеков, банальностей, но при этом немного полезного инструментария для всех остальных.
Как Вы уже поняли из заголовка речь пойдет про команды find и grep в Linux, которые позволяют используя консоль, терминал, ssh или что там у Вас еще (или как Вы это "еще" называете) искать файлы/директории по их именам/содержимому и тому подобному.
Давайте кратенько посмотрим на них.
find - синтаксис и зачем оно нужно
find — утилита поиска файлов по имени и другим свойствам, используемая в UNIX‐подобных операционных системах. С лохматых тысячелетий есть и поддерживаться почти всеми из них.
Базовый синтаксис ключей (забран с Вики):
- -name — искать по имени файла, при использовании подстановочных образцов параметр заключается в кавычки. Опция `-name' различает прописные и строчные буквы; чтобы использовать поиск без этих различий, воспользуйтесь опцией `-iname';
- -type — тип искомого: f=файл, d=каталог, l=ссылка (link), p=канал (pipe), s=сокет;
- -user — владелец: имя пользователя или UID;
- -group — владелец: группа пользователя или GID;
- -perm — указываются права доступа;
- -size — размер: указывается в 512-байтных блоках или байтах (признак байтов — символ «c» за числом);
- -atime — время последнего обращения к файлу (в днях);
- -amin — время последнего обращения к файлу (в минутах);
- -ctime — время последнего изменения владельца или прав доступа к файлу (в днях);
- -cmin — время последнего изменения владельца или прав доступа к файлу (в минутах);
- -mtime — время последнего изменения файла (в днях);
- -mmin — время последнего изменения файла (в минутах);
- -newer другой_файл — искать файлы созданные позже, чем другой_файл;
- -delete — удалять найденные файлы;
- -ls — генерирует вывод как команда ls -dgils;
- -print — показывает на экране найденные файлы;
- -print0 — выводит путь к текущему файлу на стандартный вывод, за которым следует символ ASCII NULL (код символа 0);
- -exec command {} \; — выполняет над найденным файлом указанную команду; обратите внимание на синтаксис;
- -ok — перед выполнением команды указанной в -exec, выдаёт запрос;
- -depth или -d — начинать поиск с самых глубоких уровней вложенности, а не с корня каталога;
- -maxdepth — максимальный уровень вложенности для поиска. «-maxdepth 0» ограничивает поиск текущим каталогом;
- -prune — используется, когда вы хотите исключить из поиска определённые каталоги;
- -mount или -xdev — не переходить на другие файловые системы;
- -regex — искать по имени файла используя регулярные выражения;
- -regextype тип — указание типа используемых регулярных выражений;
- -P — не разворачивать символические ссылки (поведение по умолчанию);
- -L — разворачивать символические ссылки;
- -empty — только пустые каталоги.
Примерно тоже самое, только больше и в не самом удобочитаемом виде, т.к надо делать запрос по каждому ключу отдельно, можно получить по
find -help
Результатам будет нечто такое из чего можно вычленять справку по отдельному ключу или команде (кликабельно):
В качестве развлечения можно использовать:
man find
Дабы получить мануал из самой системы по базису и ключам (тоже кликабельно);
Немного о примерах использования. Точно так же, оттуда же и тп. Просто для понимания как оно работает вообще. Наиболее просто, конечно, осознать это потренировавшись в той же консоли на реальной системе.
к содержанию ↑find примеры использования
Ищем все файлы, начиная с текущей директории, название которых начинается на sonikelf:
find . -name 'sonikelf*'
Найти все файлы, начиная с корневой директории, название которых начинается на sonikelf:
find / -name 'sonikelf*'
Поиск в директориях /usr/local/man и /opt/local/man файлов, название которых начинается на sonikelf:
find /usr/local/man /opt/local/man -name 'sonikelf*'
Ищем все файлы, начиная с текущей директории, название которых начинается на sonikelf или qu. Обратите внимание, что по умолчанию все аргументы соединены с помощью логического и (опция '-a'). Если необходимо объединить несколько аргументов логическим или — используйте ключ '-o':
find . \( -name "sonikelf*" -o -name "qu*" \) -print
Ищем графические файлы, начиная с текущего каталога (см.на кавычки):
find . -type f -regex ".*\.\(jpg\|jpeg\|gif\|png\|JPG\|JPEG\|GIF\|PNG\)"
Вывести список файлов (см. на / ) во всей файловой системе, чей размер больше 100 Мб:
find / -size +100M -print
Ищем файлы в указанных каталогах:
find /var/spool/postfix/{deferred,active,maildrop,incoming}/ -type f
Еще примеров можно поискать тут, так или здесь. Да тысячи их, но проще попрактиковаться самому, используя --help для нужного запроса и поиск в необходимой директории.
к содержанию ↑grep - что это и зачем может быть нужно
Про "репку" (как я её называю) почему-то в курсе не многие, что печалит. "Унылая" (не в обиду) формулировка из Википедии звучит примерно так:
grep — утилита командной строки, которая находит на вводе строки, отвечающие заданному регулярному выражению, и выводит их, если вывод не отменён специальным ключом.
Не сильно легче, но доступнее, можно сформулировать так:
grep — утилита командной строки, используется для поиска и фильтрации текста в файлах, на основе шаблона, который (шаблон) может быть регулярным выражением.
Если всё еще ничего не понятно, то условно говоря это удобный поиск текста везде и всюду, в особенности в файлах, директория в и тп. Удобно распарсивать логи и их содержимое, не прибегая к софту, как это бывает в Windows.
Справку можно вычленить так же как по find, т.е методом pgrep, fgrep, egrep и черт знает что еще:
man grep
Или:
help grep
Расписывать все ключи и даже основные тут (вы еще помните, что это блоговая часть сайта?) не буду, так как в отличии от find'а, последних тут вообще страшное подмножество, особенно учитывая, что существуют pgrep, fgrep, egrep и черт знает что еще, которые, в некотором смысле тоже самое, но для определенных целей.
Потрясающе удобная штука, которая жизненно необходима, особенно, если Вы что-то когда-то где-то зачем-то администрировали. Взглянем на примеры.
к содержанию ↑grep примеры использования
В принципе для работы grep не обязательно указывать даже файл или директорию, но это крайне желательно, если Вы хотите найти всё быстрее и точнее. Например:
grep sonikelf
Найдет файлы с упоминанием меня любимого, если таковые есть. Точнее не файлы, а строки с упоминанием указанного слова, т.е в данном случае sonikelf. Здесь стоит упомянуть, что строкой grep считает все символы, находящиеся между двумя символами новой строки.
grep sonikelf file.txt | поиск sonikelf в файле file.txt, с выводом полностью совпавшей строкой |
grep -o sonikelf file.txt | поиск sonikelf в файле file.txt и вывод только совпавшего куска строки |
grep -i sonikelf file.txt | игнорирование регистра при поиске |
grep -bn sonikelf file.txt | показать строку (-n) и столбец (-b), где был найден sonikelf |
grep -v sonikelf file.txt | инверсия поиска (найдет все строки, которые не совпадают с шаблоном sonikelf) |
grep -A 3 sonikelf file.txt | вывод дополнительных трех строк, после совпавшей |
grep -B 3 sonikelf file.txt | вывод дополнительных трех строк, перед совпавшей |
grep -C 3 sonikelf file.txt | вывод три дополнительные строки перед и после совпавшей |
grep -r sonikelf $HOME | рекурсивный поиск по директории $HOME и всем вложенным |
grep -c sonikelf file.txt | подсчет совпадений |
grep -L sonikelf *.txt | вывести список txt-файлов, которые не содержат sonikelf |
grep -l sonikelf *.txt | вывести список txt-файлов, которые содержат sonikelf |
grep -w sonikelf file.txt | совпадение только с полным словом sonikelf |
grep -f sonikelfs.txt file.txt | поиск по нескольким sonikelf из файла sonikelfs.txt, шаблоны разделяются новой строкой |
grep -I sonikelf file.txt | игнорирование бинарных файлов |
grep -v -f file2 file1 > file3 | вывод строк, которые есть в file1 и нет в file2 |
grep -in -e 'python' `find -type f` | рекурсивный поиск файлов, содержащих слово python с выводом номера строки и совпадений |
grep -inc -e 'test' `find -type f` | grep -v :0 | рекурсивный поиск файлов, содержащих слово python с выводом количества совпадений |
grep . *.py | вывод содержимого всех py-файлов, предваряя каждую строку именем файла |
grep "Http404" apps/**/*.py | рекурсивный поиск упоминаний Http404 в директории apps в py-файлах |
И так далее и тому подобное. Потрясающе доступный с точки зрения простоты чтения и понимания, мануал по grep'у есть например тут. Ну либо у буржуев, как и всегда (если Вы знаете английский).
к содержанию ↑Послесловие
Ну в двух словах как-то так. Быть может кто-то еще не знал, не умел или подзабыл и может быть пригодится кому-то зачем-то и где-то.
Как и всегда, если есть вопросы и, особенно, дополнения (разумные, адекватные и по делу), то добро пожаловать в комментарии к этой заметке.