А.П. Строляров, И.Г. Головин, И.А. Волкова - Операционная система Unix (1114677), страница 6
Текст из файла (страница 6)
пробелами, табуляциями,переводами строк и т.п.)Команда yes, наверное, самая простая из всех рассмотренных: онапросто построчно выводит свои аргументы в стадартный поток вывода,причем делает это в бесконечном цикле , т.е. пока не произойдет ошибкавывода, либо процесс не будет завершен (по команде kill, по сигналузавершения с клавиатуры – Ctrl-C, и т.п.). Например, команда$ yes Hello, worldбудет бесконечно (и достаточно быстро) выводитьHello,Hello,Hello,Hello,...world!world!world!world!Изначально команда yes предназначалась для формирования потокаввода для программ, задающих много вопросов и ожидающих ответа“yes” или “no”.2.9.6Команда grepКоманда grep предназначена для поиска в текстовых файлах строк,удовлетворяющих заданным условиям.
Эта команда может претендовать на звание самой сложной из разобранных здесь, хотя частные (ичастые) случаи её использования весьма просты. Например, команда$ grep include *.cотыскивает строки, содержащие слово include во файлах с расширением .c из текущей директории. Для каждой найденной строки в стандартный поток вывода выводится имя файла, двоеточие и сама найденная строка:hel.c:#include <fcntl.h>hel.c:#include <sys/stat.h>kr.c:#include <stdio.h>kr.c:#include "mod1.h"31В случае, если grep читает текст со стандартного ввода (т.е. используется как конвейерный фильтр), либо в командной строке задан всегоодин файл, на выводе имя файла и двоеточие не печатаются:$ cat *.c | grep include#include <fcntl.h>#include <sys/stat.h>#include <stdio.h>#include "mod1.h"В общем случае команда grep отыскивает в вводимом тексте (со стандартного потока ввода, либо из файлов, специфицированных в командной строке) строки, удовлетворяющие некоторому шаблону.
Шаблон задается так называемым регулярным выражением, позволяющим описывать весьма нетривиальные поисковые условия. За недостатком местамы не будем описывать здесь синтаксис и семантику регулярных выражений; заинтересованные читатели легко найдут полное описание всоответствующей документации. Простейшим случаем регулярного выражения является последовательность символов (как в примере выше).Если эта последовательность содержит пробелы или символы, имеющие специальное значение для командного интерпретатора, их можнозаключить в одинарные апострофы:$ grep ’include <’ *.chel.c:#include <fcntl.h>hel.c:#include <sys/stat.h>kr.c:#include <stdio.h>Естественно, поиском явно указанной цепочки символов возможностиgrep не ограничиваются.
Для иллюстрации отметим два часто используемых специальных символа в регулярных выражениях: символ ^ соответствует началу строки, а символ $ – концу строки. Так, команда$ grep ’ $’ *.cпоможет отыскать во всех файлы в вашей программе такие строки, вконце которых остались невидимые пробелы (отметим, что присутствиетаких пробелов считается нежелательным).Команда grep имеет достатчно большое количество опций, средикоторых отметим только две: -v заставляет искать строки, не соответствующие заданному выражению; -r позволяет производить рекурсивный поиск по всем файлам, содержащимся в заданных директориях.Так, команда32$ grep -v ’^ ’ myfileпозволяет выбрать из файла myfile все строки, кроме тех, которыеначинаются с пробела; команда$ grep -r ’^void very_strange_function(’ *позволит найти файл, в котором имеется строка, начинающаяся с цепочкиvoid very_strange_function(среди всех видимых файлов текущей директории и всех ее поддиректорий; такая команда может оказаться крайне полезной, если вы, например, забыли, в каком из файлов вашей программы описана функцияvery_strange_function, имеющая тип возвращаемого значения void.Отметим также, что команда grep завершается успешно, если быланайдена хотя бы одна строка, удовлетворяющая шаблону, и неуспешноиначе.
Данное обстоятельство используется при комбинировании команды grep с другими командами, например, find (см. ниже), а также припрограммировании на языке Bourne Shell в управляющих конструкциях(см. § 2.9.1).2.9.7Команда findЭта команда предназначена для рекурсивного поиска файлов в директориях. Вкупе с описанной выше командой grep, которая анализирует содержимое файлов, команда find представляет собой очень мощное игибкое средство поиска файлов, превосходящее по своим возможностямспециализированные средства поиска, встроенные в файл-менеджерыОС семейства Windows.Рассмотрим работу команды на ряде примеров (как всегда, полноеописание возможностей команды можно найти в оперативной документации с помощью команд man или info; см.
§2.8).$ find .выводит все файлы из текущей директории и рекурсивно из поддиректорий. Точно так же работают команды$ find . -printили33$ find -printКоманда$ find /home/igorвыводит все файлы из директории /home/igor и всех ее поддиректорий.Команда$ find . -name "*.c"выведет имена всех файлов с расширением .c из текущей директориии ее поддиректорий, например:./hel.c./kr.c./SQLTest/sqlcl.c./SQLTest/sqlsrv.cС помощью команды$ find ~ -name coreможно найти все файлы с именем core в вашей домашней директории(напомним, что командный интерпретатор преобразует символ ~ в имядомашней директории текущего пользователя).Команда$ find .
-name "*.c" -exec grep include {} \;отыскивает и выводит в стандартный поток вывода все строки, содержащие слово include, из файлов с расширением .c, находящихся втекущей директории или в её поддиректориях. Разберем эту командуподробнее. Точка означает, что find должен перебрать все файлы изтекущей директории и из её поддиректорий.
Предложение -name "*.c"означает, что отбираются только файлы с именем, удовлетворяющимзаданной маске, т.е. с расширением .c. -exec include {} \; означает, что вместо вывода имени файла для каждого отобранного именифайла запускается команда grep со строкой include и именем файла вкачестве аргументов, т.е. имя отобранного файла подставляется вместо{}. Конец команды, которую должен выполнить -exec, обозначаетсясимволом “;”, который мы экранируем обратной косой чертой, чтобыинтерпретатор не воспринял его как разделитель двух команд.34Результат команды grep выводится в стандартный поток вывода(при этом grep работает в режиме фильтра, т.е.
имя файла перед строкой не печатается).Если мы хотим увидеть также имя файла, в котором встретиласьнайденная строка, то можно выдать следующую команду:$ find . -name "*.c" -exec grep include {}\; -printВ результате будет выдано#include <fcntl.h>#include <sys/stat.h>./hel.c#include "stdio.h"./kr.cт.е. после запуска команды grep (и её успешного завершения!) по опции-print выполняется вывод имени файла.В общем случае, в команде find нужно задать два объекта: местоположение файлов и выражение, вычисляемое для каждого имени файла.Местоположение файлов – это список файловых имен (допускаютсямаски имен файлов).
Если файловое имя, указанное в команде или подходящее под маску, соответствует поддиректории, то выбираются (рекурсивно) все файлы из этой поддиректории. По умолчанию в качествеместоположения выбирается текущая директория (.). Например:$ find /home/igor/*.h /usr/include/*.h /usr/local/include/*.hЗдесь перебираются все файлы с расширением .h из директорий/home/igor, /usr/include и /usr/local/include.
Файлы из поддиректорий выбираться не будут, за исключением маловероятного случая,когда в указанных директориях существует поддиректория с расширением h. В этом случае будут выбраны ВСЕ файлы из данной поддиректории, включая файлы из её поддиректорий.Ключевое значение для понимания работы команды find играет понятие выражения. Для каждого выбранного файла это выражение вычисляется, причем в процессе вычисления выражения над файлом могут выполняться какие-либо команды (как в примере с командой grepвыше).
По умолчанию выражением является опция -print, результатомвычисления которой будет вывод полного имени файла в стандартныйпоток вывода. Значением каждого выражения является логическое значение (истина или ложь).Простейшим случаем выражения является опция (начинающаяся сознака минус). Примеры опций:35• -print – выводит полное имя файла. Всегда истинна.• -name NAME – истинна, если имя файла (без полного пути) соответствует NAME. Например, -name core выбирает файлы с именемcore; -name "*.c" выбирает файлы с расширением .c.• -perm MODE – истинна для файлов, права доступа к которым совпадают с константой MODE. Например, -perm 666 выбирает тольконеисполняемые файлы, доступные на чтение и запись для любогопользователя.• -exec COMMAND ;. – при вычислении выполняет команду COMMAND.При этом выбранное имя файла подставляется вместо комбинации символов {} Истинность опции определяется успехом (“истина”) или неуспехом (“ложь”) выполнения команды COMMAND.Обычно символ “;”, ограничивающий выполняемую команду, приходится экранировать (то есть ставить перед ним символ \), чтобыинтерпретатор командной строки не принял его за свой спецсимвол.
Пример опции -exec разобран выше.Существует большое количество опций команды find, которые, вчастности, позволяют отбирать файлы по временам (создания, модификации и т.п.), правам доступа, владельцам, задавать более тонкие,чем показанные выше, критерии отбора имени файла (регулярные выражения, игнорирование регистра, глубина поиска в поддиректориях,тип файловой системы) и т.д. и т.п.Выражения (опции) могут комбинироваться с помощью логическихопераций. По умолчанию, в качестве операции берется коньюнкция, т.е.expr1 expr2 означает, что выражение expr2 будет выполняться, толькоесли выражение expr1 истинно. Именно поэтому в команде$ find . -exec grep main {} \; -printопция -print будет вычислена (выполнена) и полное имя файла выведено, только если команда grep нашла в выбранном файле (а выбираютсявсе файлы из текущей директории и её поддиректорий) строку main.