find, locate, whereis и grep

Команды find, locate, whereis и grep - мощные инструменты поиска файлов. Мы рассмотрим наиболее основные варианты их применения, поскольку полное описание потребовало бы целой главы. Полное описание каждой команды можно найти на соответствующих страницах руководства (команду обращения к ним рассмотрена далее).

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

find

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

Эта команда позволяет отыскивать файлы по имени, дате создания или модификации, владельцу (обычно, это создатель файла), объему и даже типу файла. Мы рассмотрим лишь самый распространенный способ поиска - по имени файла.

Основная структура команды find следующая.

$ find starting-directory parameters actions

Параметр starting-directory определяет каталог, с которого должен начинаться поиск. Например, если в качестве этого параметра указать /home, поиск будет проводиться во всех подкаталогах каталога /home - в исходных каталогах пользователей. Если указать одну косую (/), будет выполнен поиск по всем каталогам.

Параметр parameters означает критерии поиска. В нашем случае, это имя 'файла, который надо найти (-name имя_ файла).

Параметр actions указывает, что делать с найденными файлами. Чаще всего указывается флажок -print, по которому выводится имя найденного файла с указанием пути. Задавать поиск без этого параметра бессмысленно, поскольку результат останется неизвестным.

Подытожим. Чтобы найти в системе все файлы с именем foo, введите следующую команду.

$ find / -name foo -print

На экране результат будет выглядеть примерно так:

$ find / -name foo -print

/trap/foo

/home/armand/foo

/home/tdanesh/foo

Совет

Обратите внимание: в предыдущем примере задавался поиск во всей системе. Чтобы такая операция была возможна, необходимо войти в систему как корневой пользователь, которому доступны все каталоги. Если этого не сделать, то в ответ на каждую попытку провести поиск в каталоге, к которому нет доступа, будет выводиться сообщение об ошибке "permission denied" (нет доступа).

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

$ find / -name 'fo*' -print

/tmp/foo

/var/lib/texmf/fonts

/usr/bin/font2c

/usr/bin/mh/folders

/usr/bin/mh/folder

/usr/bin/mh/forw

/usr/bin/formail

/usr/bin/fontexport

/usr/bin/fontimport

/usr/bin/fold

и т.д.

Обратите внимание: имя файла указано в одинарных кавычках 'fо*'. Если не сделать этого при использований подстановочного символа "*", то ответом на ввод команды будет сообщение об ошибке.

$ find / -name fo* -print -mount

find: paths must precede expression Usage: find [path...] [expression]

Если результаты выполнения команды find не помещаются на экране, можно присоединить к ней команду more, как в примере с командой ls -1.

$ find / -name 'fo*' -print | more

Locate

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

Например, команда locate xauth породит следующий результат:

$ locate xauth

/home/mj/.xauth

/home/mj/.xauth/refcount

/home/mj/.xauth/refcount/root

/home/mj7 .xauth/refcount/root/testlinux

/lib/security/pam_xauth.so

/usr/XllR6/bin/mkxauth

/usr/XllR6/bin/xauth

/usr/XllR6/man/manl/mkxauth.1x.gz

/usr/XllR6/man/manl/xauth.1x.gz

/usr/share/doc/pam-0.72/txts/READmE.pam_xauth

/usr/share/man/man8/pam_xauth.8.gz

Обратите внимание, что эта команда выдала полный путь для всех файлов и каталогов, имена которых включают строку "xauth," в том числе каталоги /home/mj / .xauth и /usr/X11R6/ bin/mkxauth, а также файл команды /usr/X11R6/bin/xauth.

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

Whereis

Если вы ищете команду с известным названием, воспользуйтесь whereis, чтобы найти, в каком каталоге расположена искомая команда, ее исходный код и соответствующая страница документации. В отличие от find или locate, здесь вам потребуется точное знание названия команды. Например, команда whereis fdisk выдаст следующий результат:

$ whereis fdisk

fdisk: /sbin/fdisk /usr/share/man/man8/fdisk,8.gz

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

К недостаткам команды whereis можно отнести то, что она просматривает только каталоги, включенные в специальный список. По этой причине она не сможет найти новую команду или страницу руководства, которую вы только что инсталлировали.

Grep

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

Предположим, у вас есть текстовый файл, содержащий слово "radio". Вы записали этот файл в исходный каталог, но забыли его имя. Следовательно, надо найти файл, который содержит слово "radio". Именно такой поиск выполняется по команде grep.

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

$ grep radio *

ab.txt:This is a tes.t of searching for the word radio. pop.txt:

0n another radio station, he found that

Обратите внимание: команда grep выводит по одной строке на каждое найденное слово "radio". Справа от имени файла после двоеточия приведена строка, содержащая искомое слово. Общий формат команды grep следующий.

$ grep text-pattern file-list

В качестве строки поиска text-pattern можно указать слово, фразу или более сложное регулярное выражение. Регулярные выражения - мощное средство поиска текста. Их описание можно найти на странице руководства команды grep. Список файлов file-list может быть любой формы, допускаемой оболочкой. Типы выражений, составляющие список файлов, рассмотрены в гл. 16.

Обычно проверка одного файла проводится командой:

$ grep text-pattern file-name

а проверка всех файлов некоторого каталога командой:

$ grep text-pattern *

В последней команде "*" - это выражение, означающее поиск во всех файлах текущего каталога. Строка поиска в простейшем варианте представляет собой слово или часть слова без пробелов. Если надо найти фразу, например "is a test", от ее указывают в двойных кавычках, как в следующем примере:

$ "grep "is a test"*

ab.txt:This is a test of searching for the word radio.

Подобно командам more и less, команду grep удобно конвейеризировать с другими командами. Предположим, что нам необходимо получить список всех файлов в текущем каталоге с датой модификации 12 мая. Для этого можно воспользоваться командой 1s -1 с присоединенной командой grep:

$ 1s -1 | grep "may 12"

-rw-r—r-- 1 root root 19197 may 12 21:17 rfbprotoheader.pdf

-rw-r—r- 1 root root 110778 may 12 21:20 rfprotoA.zip

-rw-r—r--- 1 root root 17692 may 12 23:03 svnc-0 .1. tar ,gz

-rw-r—r-- l root root 25222 may 12 19:58 vnc-3 . 3 . l_j-avasrc . tgz

drwxr-xr-x 2 root root 1024 may 12 21:49 vncj.ava

Команды и кавычки

Существует три разновидности кавычек, используемых в командах: одиночная ('), двойная (") и обратная ('), Эти кавычки отличаются с точки зрения встроенных команд, наподобие date, и переменных, наподобие $LOGNAmE. Пара любых одинаковых кавычек ограничивает передаваемую команде строку данных. Например, допустим, что $LOGNAmE=mj и сравним следующие команды:

echo Welcome $LOGUAmE, the date is date

echo Welcome $LOGNAmE, the date is date'

echo "Welcome $LOGNAmE, the date is date"

echo "Welcome $LOGNAmE, the date is 'date'"

В зависимости от того, насколько корректно указаны кавычки, Linux будет (или не будет) выполнять команду date или транслировать $LOGNAmE. Результаты выглядят так:

Welcome mj, the date is date

Welcome $LGGNAmE, the date is /Sate

Welcome mj, the date is date

Welcome mj, the .date is mon June 14 10:45:20 EDT 2001

Первый пример не содержит кавычек вообще. $LOGNAmE транслируется как mj, но команда date не выполняется. Во втором примере использованы одиночные кавычки. $LOGNAmE не транслируется, а команда date не выполняется. Третий пример содержит двойные кавычки. Результат совпадает с результатом первой команды, поэтому двойные кавычки полезны в таких командах как grep. Последний пример заключает date в обратные кавычки. Такая процедура позволяет выполнить команду Linux, входящую в состав текстовой строки.