Что такое поиск по шаблону в Linux

Обновлено: 21.11.2024

Фильтр grep ищет в файле определенный шаблон символов и отображает все строки, содержащие этот шаблон. Шаблон, который ищется в файле, называется регулярным выражением (grep означает глобальный поиск регулярного выражения и вывод).
Синтаксис:

Примеры команд

Рассмотрите приведенный ниже файл в качестве входных данных.

<р>1. Поиск без учета регистра: опция -i позволяет искать строку без учета регистра в заданном файле. Соответствует таким словам, как «UNIX», «Unix», «unix».

Вывод:

<р>2. Отображение количества совпадений: мы можем найти количество строк, соответствующих заданной строке/шаблону

Вывод:

<р>3. Отобразить имена файлов, соответствующие шаблону: мы можем просто отобразить файлы, содержащие заданную строку/шаблон.

Вывод:

<р>4. Проверка всех слов в файле: по умолчанию grep соответствует заданной строке/шаблону, даже если он найден как подстрока в файле. Опция -w для grep заставляет искать только целые слова.

Вывод:

<р>5. Отображение только совпадающего шаблона: по умолчанию grep отображает всю строку, содержащую совпадающую строку. Мы можем заставить grep отображать только совпадающую строку, используя параметр -o.

Вывод:

<р>6. Показать номер строки при отображении вывода с помощью grep -n : чтобы показать номер строки файла с соответствующей строкой.

Вывод:

<р>7. Инвертирование соответствия шаблону: Вы можете отобразить строки, которые не соответствуют указанному шаблону строки поиска, используя параметр -v.

Вывод:

<р>8. Сопоставление строк, начинающихся со строки: шаблон регулярного выражения ^ указывает начало строки. Это можно использовать в grep для сопоставления строк, начинающихся с заданной строки или шаблона.

Вывод:

<р>9. Сопоставление строк, заканчивающихся строкой: шаблон регулярного выражения $ указывает конец строки. Это можно использовать в grep для сопоставления строк, которые заканчиваются данной строкой или шаблоном.

10.Указывает выражение с опцией -e. Можно использовать несколько раз :

<р>11. -f опция файла Берет шаблоны из файла, по одному на строку.

<р>12. Вывести n определенных строк из файла: -A выводит искомую строку и n строк после результата, -B печатает искомую строку и n строк до результата, а -C печатает искомую строку и n строк после и до результата.

Синтаксис:

Пример:

Вывод:

Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное или хотите поделиться дополнительной информацией по теме, обсуждаемой выше.

В этом руководстве подробно описаны наиболее полезные команды grep для систем Linux/Unix.

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

  • Linux или UNIX-подобная система
  • Доступ к терминалу/командной строке
  • Пользователь с разрешениями на доступ к нужным файлам и каталогам

Примечание. Строка не представляет собой строку текста, отображаемую на экране терминала. Строка в текстовом файле представляет собой последовательность символов до тех пор, пока не будет введен разрыв строки. Вывод команд grep может содержать целые абзацы, если параметры поиска не уточнены.

Что такое команда grep?

Grep — это аббревиатура, расшифровывающаяся как Global Regular Expression Print.

Grep — это инструмент командной строки Linux/Unix, используемый для поиска строки символов в указанном файле. Шаблон текстового поиска называется регулярным выражением. Когда он находит совпадение, он печатает строку с результатом. Команда grep удобна при поиске в больших файлах журналов.

Использование команды grep

Команда grep в своей основной форме состоит из трех частей. Первая часть начинается с grep, за которой следует искомый шаблон. После строки идет имя файла, в котором ищет grep.

Простейший синтаксис команды grep выглядит следующим образом:

Команда может содержать множество параметров, вариантов шаблонов и имен файлов. Комбинируйте столько вариантов, сколько необходимо, чтобы получить нужные результаты. Ниже приведены наиболее распространенные команды grep с примерами.

Примечание. Grep чувствителен к регистру. Обязательно используйте правильный регистр при выполнении команд grep.

Чтобы найти файл

Чтобы напечатать любую строку из файла, содержащего определенный набор символов, в нашем случае phoenix в файле sample2 , выполните команду:

Grep отобразит каждую строку, в которой есть совпадение со словом phoenix . При выполнении этой команды вы не получите точных совпадений. Вместо этого терминал печатает строки со словами, содержащими введенную вами строку символов. Вот пример:

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

Поиск в нескольких файлах

Чтобы найти несколько файлов с помощью команды grep, вставьте имена файлов, которые вы хотите найти, разделив их пробелом.

В нашем случае команда grep для сопоставления слова phoenix в трех файлах sample , sample2 и sample3 выглядит следующим образом:

Терминал печатает имя каждого файла, содержащего совпадающие строки, и фактические строки, содержащие требуемую строку символов.

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

Совет: обратитесь к нашей статье Команды Xargs, чтобы узнать, как использовать xargs с grep для поиска строки в списке файлов.

Поиск во всех файлах в каталоге

Чтобы найти все файлы в текущем каталоге, используйте звездочку вместо имени файла в конце команды grep.

В этом примере мы используем nix в качестве критерия поиска:

Вывод показывает имя файла с nix и возвращает всю строку.

Найти только целые слова

Grep позволяет находить и печатать результаты только для целых слов. Чтобы найти слово phoenix во всех файлах в текущем каталоге, добавьте -w к команде grep.

Эта опция печатает только строки с полным совпадением слов и именами файлов, в которых они были найдены:

Если параметр -w опущен, grep отображает шаблон поиска, даже если он является подстрокой другого слова.

Если вы хотите найти несколько строк и шаблонов слов, ознакомьтесь с нашей статьей о том, как выполнить поиск нескольких строк, шаблонов или слов.

Игнорировать регистр при поиске Grep

Поскольку команды grep чувствительны к регистру, одним из наиболее полезных операторов для поиска grep является -i. Вместо того, чтобы печатать результаты только в нижнем регистре, терминал отображает результаты как в верхнем, так и в нижнем регистре. Вывод включает строки с записями смешанного регистра.

Пример этой команды:

Если мы используем оператор -i для поиска файлов phoenix в текущем каталоге, результат будет выглядеть следующим образом:

Искать в подкаталогах

Чтобы включить в поиск все подкаталоги, добавьте оператор -r к команде grep.

Эта команда выводит совпадения для всех файлов в текущем каталоге, подкаталогах и точный путь с именем файла. В приведенном ниже примере мы также добавили оператор -w для отображения целых слов, но форма вывода осталась прежней.

Обратный поиск grep

Вы можете использовать grep для вывода всех строк, которые не соответствуют определенному шаблону символов. Чтобы инвертировать поиск, добавьте -v к команде grep.

Чтобы исключить все строки, содержащие phoenix , введите:

Терминал печатает все строки, не содержащие слова, используемого в качестве критерия поиска. Используйте -i, чтобы игнорировать регистр, чтобы полностью исключить слово, используемое для этого поиска:

Показать строки, точно соответствующие строке поиска

Команда grep печатает целые строки, когда находит совпадение в файле.Чтобы напечатать только те строки, которые полностью соответствуют строке поиска, добавьте параметр -x.

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

Вот сравнение результатов без оператора -x и с ним в нашей команде grep:

Чтобы получить список имен совпадающих файлов

Иногда вам нужно только увидеть имена файлов, которые содержат слово или строку символов, и исключить фактические строки. Чтобы вывести только те имена файлов, которые соответствуют вашему запросу, используйте оператор -l:

Вывод показывает точные имена файлов, которые содержат phoenix в текущем каталоге, но не печатает строки с соответствующим словом:

Напоминаем, что используйте оператор рекурсивного поиска -r, чтобы включить в поиск все подкаталоги.

Чтобы подсчитать количество совпадений

Grep может отображать имена файлов и количество строк, в которых он находит совпадения с вашим словом.

Используйте оператор -c, чтобы подсчитать количество совпадений:

Отображение количества строк до или после строки поиска

Иногда вам нужно больше контента в результатах поиска, чтобы решить, что наиболее релевантно.

Используйте следующие операторы, чтобы добавить нужные строки до, после совпадения или и то, и другое:

  • Используйте -A и количество строк для отображения после совпадения: grep -A 3 phoenix sample — эта команда печатает три строки после совпадения.
  • Используйте -B и количество строк для отображения перед совпадением: grep -B 2 phoenix sample — эта команда выводит две строки перед совпадением.
  • Используйте -C и несколько строк для отображения до и после совпадения: grep -C 2 phoenix sample — эта команда выводит две строки до и после совпадения.

Отображение номеров строк с совпадениями grep

Когда grep выводит результаты с большим количеством совпадений, удобно видеть номера строк. Добавьте оператор -n к любой команде grep, чтобы отобразить номера строк.

Мы будем искать Phoenix в текущем каталоге, покажем две строки до и после совпадений вместе с их номерами строк.

Ограничить вывод grep фиксированным количеством строк

Отдельные файлы, например файлы журналов, могут содержать множество совпадений с шаблонами поиска grep. Ограничьте количество строк в выводе grep, добавив в команду параметр -m и число.

В этом случае терминал распечатает первые два совпадения, найденные в файле примера.

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

Теперь вы знаете, как использовать команду grep в Linux/Unix.

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

Команда grep — одна из самых полезных команд в терминальной среде Linux. Название grep расшифровывается как «глобальная печать регулярных выражений». Это означает, что вы можете использовать grep, чтобы проверить, соответствует ли полученный ввод заданному шаблону. Эта, казалось бы, тривиальная программа чрезвычайно эффективна; его способность сортировать ввод на основе сложных правил делает его популярным звеном во многих цепочках команд.

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

Предпосылки

Чтобы следовать этому руководству, вам потребуется доступ к компьютеру с операционной системой на базе Linux. Это может быть либо виртуальный частный сервер, к которому вы подключились с помощью SSH, либо ваша локальная машина. Обратите внимание, что это руководство было проверено с использованием сервера Linux под управлением Ubuntu 20.04, но приведенные примеры должны работать на компьютере с любой версией любого дистрибутива Linux.

Если вы планируете использовать удаленный сервер, чтобы следовать этому руководству, мы рекомендуем вам сначала выполнить наше руководство по начальной настройке сервера. Это создаст безопасную серверную среду, включая пользователя без полномочий root с привилегиями sudo и брандмауэр, настроенный с помощью UFW, которые вы сможете использовать для развития своих навыков работы с Linux.

В качестве альтернативы мы рекомендуем вам использовать интерактивный терминал, встроенный на этой странице, чтобы поэкспериментировать с примерами команд из этого руководства. Щелкните следующее Запустить интерактивный терминал! кнопку, чтобы открыть окно терминала и начать работу в среде Linux (Ubuntu).

Запустите интерактивный терминал!

Основное использование

В этом руководстве вы будете использовать grep для поиска различных слов и фраз в Стандартной общественной лицензии GNU версии 3.

Если вы работаете в системе Ubuntu, вы можете найти файл в папке /usr/share/common-licenses. Скопируйте его в свой домашний каталог:

Если вы работаете в другой системе, используйте команду curl для загрузки копии:

В этом руководстве вы также будете использовать файл лицензии BSD. В Linux вы можете скопировать это в свой домашний каталог с помощью следующей команды:

Если вы работаете в другой системе, создайте файл с помощью следующей команды:

Теперь, когда у вас есть файлы, вы можете начать работать с grep .

В самой простой форме вы используете grep для сопоставления литеральных шаблонов в текстовом файле. Это означает, что если вы передадите grep слово для поиска, он распечатает каждую строку в файле, содержащую это слово.

Выполните следующую команду, чтобы использовать grep для поиска каждой строки, содержащей слово GNU:

Первый аргумент, GNU, — это искомый шаблон, а второй аргумент, GPL-3, — входной файл, который вы хотите найти.

Результатом будет каждая строка, содержащая текст шаблона:

В некоторых системах искомый шаблон будет выделен в результатах поиска.

Общие параметры

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

Если вы хотите, чтобы grep игнорировал регистр вашего параметра поиска и выполнял поиск как в верхнем, так и в нижнем регистре, вы можете указать параметр -i или --ignore-case.

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

Результаты содержат: ЛИЦЕНЗИЯ , лицензия и Лицензия :

Если бы существовал экземпляр с LiCeNsE , он также был бы возвращен.

Если вы хотите найти все строки, не содержащие указанный шаблон, вы можете использовать параметр -v или --invert-match.

Выполните поиск каждой строки, не содержащей слова the, в лицензии BSD с помощью следующей команды:

Вы получите следующие выходные данные:

Поскольку вы не указали параметр «игнорировать регистр», последние два элемента были возвращены без слова the .

Часто бывает полезно знать номер строки, в которой происходит совпадение. Вы можете сделать это, используя опцию -n или --line-number. Повторно запустите предыдущий пример с добавлением этого флага:

Это вернет следующий текст:

Теперь вы можете указать номер строки, если хотите внести изменения в каждую строку, не содержащую расширение . Это особенно удобно при работе с исходным кодом.

Регулярные выражения

Во введении вы узнали, что grep означает «глобальная печать регулярных выражений». «Регулярное выражение» — это текстовая строка, описывающая определенный шаблон поиска.

Разные приложения и языки программирования реализуют регулярные выражения немного по-разному. В этом руководстве вы будете изучать лишь небольшую часть того, как grep описывает свои шаблоны.

Буквальные совпадения

В предыдущих примерах этого руководства при поиске слов GNU и . Шаблоны, точно определяющие символы, которые должны сопоставляться, называются «литералами», поскольку они соответствуют шаблону буквально, посимвольно.

Полезно думать о них как о совпадении строки символов, а не о совпадении слова. Это станет более важным отличием по мере того, как вы будете изучать более сложные шаблоны.

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

Якорные совпадения

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

Например, используя якоря, вы можете указать, что хотите знать только о строках, которые соответствуют GNU в самом начале строки.Для этого вы можете использовать привязку ^ перед литеральной строкой.

Выполните следующую команду, чтобы выполнить поиск в файле GPL-3 и найти строки, в которых GNU встречается в самом начале строки:

Эта команда вернет следующие две строки:

Аналогичным образом вы используете якорь $ в конце шаблона, чтобы указать, что совпадение будет действительным только в том случае, если оно находится в самом конце строки.

Эта команда будет сопоставлять каждую строку, заканчивающуюся словом и в файле GPL-3:

Вы получите следующие выходные данные:

Соответствие любому символу

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

Например, чтобы сопоставить что-либо в файле GPL-3, содержащем два символа, а затем строку cept , вы должны использовать следующий шаблон:

Эта команда возвращает следующий вывод:

В этом выводе есть экземпляры accept и exclude, а также варианты этих двух слов. Шаблон также соответствовал бы z2cept, если бы он тоже был найден.

Выражения в квадратных скобках

Поместив группу символов в квадратные скобки ( \[ и \] ), вы можете указать, что символ в этой позиции может быть любым символом, найденным в группе квадратных скобок.

Например, чтобы найти строки, содержащие too или two , нужно кратко указать эти варианты, используя следующий шаблон:

Вывод показывает, что в файле существуют оба варианта:

Обозначение скобок дает вам несколько интересных вариантов. Вы можете сделать так, чтобы шаблон соответствовал чему угодно, кроме символов в скобках, начав список символов в скобках с символа ^.

Этот пример похож на шаблон .ode , но не соответствует коду шаблона:

Вот что вы получите:

Обратите внимание, что во второй возвращаемой строке действительно есть слово code . Это не ошибка регулярного выражения или grep. Вернее, эта строка была возвращена, потому что ранее в строке был найден шаблонный мод, найденный в слове модель. Строка была возвращена, поскольку существовал экземпляр, соответствующий шаблону.

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

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

Вот что возвращает это выражение:

Из-за некоторых устаревших проблем с сортировкой зачастую точнее использовать классы символов POSIX, а не диапазоны символов, как вы только что использовали.

Обсуждение каждого класса символов POSIX выходит за рамки этого руководства, но пример, который выполняет ту же процедуру, что и в предыдущем примере, использует класс символов \[:upper:\] в селекторе скобок:

Вывод будет таким же, как и раньше.

Повторить шаблон ноль или больше раз

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

Чтобы найти каждую строку в файле GPL-3, содержащую открывающую и закрывающую круглую скобку, содержащую только буквы и одиночные пробелы между ними, используйте следующее выражение:

Вы получите следующий результат:

До сих пор вы использовали точки, звездочки и другие символы в своих выражениях, но иногда вам нужно искать именно эти символы.

Экранирование метасимволов

В некоторых случаях вам нужно искать буквальную точку или буквальную открывающую скобку, особенно при работе с исходным кодом или файлами конфигурации. Поскольку эти символы имеют особое значение в регулярных выражениях, вам нужно «экранировать» эти символы, чтобы сообщить grep, что вы не хотите использовать их специальное значение в этом случае.

Вы экранируете символы, используя обратную косую черту ( \ ) перед символом, который обычно имеет особое значение.

Например, чтобы найти любую строку, начинающуюся с заглавной буквы и заканчивающуюся точкой, используйте следующее выражение, которое избегает конечной точки, чтобы оно представляло буквальную точку вместо обычного значения «любой символ»:

Вот что вы увидите:

Теперь давайте рассмотрим другие параметры регулярных выражений.

Расширенные регулярные выражения

Команда grep поддерживает более расширенный язык регулярных выражений, используя флаг -E или вызывая команду egrep вместо grep .

Эти параметры открывают возможности «расширенных регулярных выражений». Расширенные регулярные выражения включают все основные метасимволы, а также дополнительные метасимволы для более сложных совпадений.

Группировка

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

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

Чередование

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

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

Следующее содержит в тексте либо GPL, либо Стандартную общественную лицензию:

Вывод выглядит следующим образом:

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

Квантификаторы

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

Чтобы соответствовать символу ноль или один раз, вы можете использовать ? персонаж. Это делает символы или наборы символов, которые были раньше, необязательными, по сути.

Следующее соответствует авторскому праву и праву, помещая копию в необязательную группу:

Вы получите следующие выходные данные:

Символ + соответствует выражению один или несколько раз. Это почти как метасимвол *, но с символом + выражение должно совпасть хотя бы один раз.

Следующее выражение соответствует строке free плюс один или несколько символов, не являющихся пробелами:

Вы увидите следующий вывод:

Указание повторения совпадения

Чтобы указать количество повторений совпадения, используйте фигурные скобки (< и >). Эти символы позволяют указать точное число, диапазон или верхнюю или нижнюю границу количества совпадений выражения.

Используйте следующее выражение, чтобы найти все строки в файле GPL-3, содержащие тройные гласные:

В каждой возвращаемой строке есть слово с тремя гласными:

Чтобы сопоставить любые слова, содержащие от 16 до 20 символов, используйте следующее выражение:

Вот вывод этой команды:

Отображаются только строки, содержащие слова указанной длины.

Заключение

grep полезен для поиска шаблонов в файлах или в иерархии файловой системы, поэтому стоит потратить время на ознакомление с его параметрами и синтаксисом.

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

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

Хотите узнать больше? Присоединяйтесь к сообществу DigitalOcean!

Присоединяйтесь к нашему сообществу DigitalOcean, насчитывающему более миллиона разработчиков, бесплатно! Получайте помощь и делитесь знаниями в нашем разделе "Вопросы и ответы", находите руководства и инструменты, которые помогут вам расти как разработчику и масштабировать свой проект или бизнес, а также подписывайтесь на интересующие вас темы.

Точно так же, как многие из нас сейчас используют слово "Google" в качестве глагола, означающего "найти", программисты Unix часто используют слово "grep". «grep» — это сокращение от «global/regular expression/print», обычной последовательности операций в ранних текстовых редакторах Unix. Это также название очень полезной программы командной строки.

grep находит и печатает строки в файлах, соответствующие шаблону. Для наших примеров мы будем использовать файл, содержащий три хайку, взятых с конкурса 1998 года в журнале Salon. Для этого набора примеров мы будем работать в подкаталоге записи:

Навсегда или на пять лет

Мы не дали ссылки на оригинальные хайку, потому что их больше нет на сайте Salon. Как сказал Джефф Ротенберг, «цифровая информация хранится вечно — или пять лет, в зависимости от того, что наступит раньше». К счастью, у популярного контента часто есть резервные копии.

Найдем строки, содержащие слово «не»:

Здесь нет шаблона, который мы ищем. Команда grep ищет в файле совпадения с указанным шаблоном. Чтобы использовать его, введите grep , затем шаблон, который мы ищем, и, наконец, имя файла (или файлов), в котором мы ищем.

Вывод — это три строки в файле, содержащие буквы "не".

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

Давайте найдем шаблон: "The".

На этот раз выводятся две строки, содержащие буквы «The», одна из которых содержит наш шаблон поиска внутри более крупного слова «Thesis».

Чтобы ограничить совпадения строками, содержащими слово «The» отдельно, мы можем указать grep с параметром -w. Это ограничит совпадения границами слов.

Позже в этом уроке мы также увидим, как можно изменить поведение команды grep при поиске в зависимости от ее чувствительности к регистру.

Обратите внимание, что "граница слова" включает в себя начало и конец строки, а не только буквы, окруженные пробелами. Иногда мы хотим искать не одно слово, а фразу. Это также легко сделать с помощью grep, заключив фразу в кавычки.

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

Еще один полезный параметр -n , который нумерует совпадающие строки:

Здесь мы видим, что строки 5, 9 и 10 содержат буквы «it».

Мы можем комбинировать параметры (например, флаги), как и с другими командами Unix. Например, давайте найдем строки, содержащие слово «the». Мы можем комбинировать опцию -w, чтобы найти строки, содержащие слово «the», и -n, чтобы пронумеровать совпадающие строки:

Теперь мы хотим использовать параметр -i, чтобы сделать наш поиск нечувствительным к регистру:

Теперь мы хотим использовать параметр -v, чтобы инвертировать наш поиск, т. е. мы хотим вывести строки, которые не содержат слова «the».

Если мы используем параметр -r (рекурсивный), grep может рекурсивно искать шаблон в наборе файлов в подкаталогах.

Давайте рекурсивно поищем Yesterday в каталоге shell-lesson-data/exercise-data/writing:

grep имеет много других опций. Чтобы узнать, что это такое, мы можем ввести:

Использование grep

Какая команда приведет к следующему выводу:

  1. grep "из" haiku.txt
  2. grep -E "из" haiku.txt
  3. grep -w "из" haiku.txt
  4. grep -i "из" haiku.txt

Решение

Правильный ответ — 3, потому что параметр -w ищет только совпадения целых слов. Другие варианты также будут соответствовать «из», если они являются частью другого слова.

Подстановочные знаки

Однако реальная сила grep заключается не в его параметрах; это происходит из-за того, что шаблоны могут включать подстановочные знаки. (Техническое название для них — регулярные выражения, что означает «re» в «grep».) Регулярные выражения одновременно сложны и мощны; если вы хотите выполнять сложные поиски, посмотрите урок на нашем сайте. Как дегустатор, мы можем найти строки с буквой «о» во второй позиции, например:

Мы используем параметр -E и помещаем шаблон в кавычки, чтобы оболочка не пыталась его интерпретировать. (Если шаблон содержит, например, * , оболочка попытается расширить его перед запуском grep .) Символ ^ в шаблоне привязывает совпадение к началу строки. . соответствует одиночному символу (точно так же, как ? в оболочке), а o соответствует фактическому 'o'.

Отслеживание вида

У Лии есть несколько сотен файлов данных, сохраненных в одном каталоге, каждый из которых имеет следующий формат:

Она хочет написать сценарий оболочки, который принимает вид в качестве первого аргумента командной строки и каталог в качестве второго аргумента. Сценарий должен вернуть один файл с именем spec.txt, содержащий список дат и количество видов, встречавшихся в каждую дату. Например, используя приведенные выше данные, файл rabbit.txt будет содержать:

Расположите эти команды и конвейеры в правильном порядке, чтобы добиться этого:

Подсказка: используйте man grep, чтобы найти способ рекурсивного поиска текста в каталоге, и man cut, чтобы выбрать более одного поля в строке.

Пример такого файла предоставляется в оболочке- данные урока/упражнения-данные/количество животных/animals.csv

Решение

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

Сценарий выше можно вызвать следующим образом:

Маленькие женщины

Вы и ваш друг только что закончили читать Маленькие женщины Луизы Мэй Олкотт и спорите. Из четырех сестер в книге, Джо, Мэг, Бет и Эми, ваш друг считает, что Джо была упомянута больше всего. Вы, однако, уверены, что это была Эми. К счастью, у вас есть файл LittleWomen.txt, содержащий полный текст романа (shell-lesson-data/exercise-data/writing/LittleWomen.txt). Используя цикл for, как бы вы подсчитали, сколько раз упоминается каждая из четырех сестер?

Подсказка: в одном из решений могут использоваться команды grep и wc и | , а другой может использовать параметры grep. Часто существует несколько способов решения задачи программирования, поэтому конкретное решение обычно выбирается на основе сочетания получения правильного результата, элегантности, удобочитаемости и скорости.

Решения

Альтернативное, немного худшее решение:

Это решение хуже, потому что команда grep -c сообщает только о количестве совпадающих строк. Общее количество совпадений, о которых сообщает этот метод, будет ниже, если в каждой строке будет более одного совпадения.

Внимательные наблюдатели могли заметить, что имена персонажей иногда появляются в заголовках глав полностью прописными буквами (например, «MEG ИДЕТ НА ЯРМАРКУ Тщеславия»). Если вы хотите подсчитать и их, вы можете добавить параметр -i для нечувствительности к регистру (хотя в этом случае это не повлияет на ответ на вопрос, какая сестра упоминается чаще всего).

В то время как команда grep ищет строки в файлах, команда find находит сами файлы. Опять же, у него много вариантов; чтобы показать, как работают самые простые, мы будем использовать дерево каталогов shell-lesson-data/exercise-data, показанное ниже.

Каталог упражнений-данных содержит один файл, numbers.txt и четыре папки: Animal-Counts , Creations , Proteins и Writing, содержащие различные файлы.

Для нашей первой команды запустим find . (не забудьте запустить эту команду из папки shell-lesson-data/exercise-data).

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

Первая опция в нашем списке — это -type d, что означает «вещи, которые являются каталогами». Разумеется, вывод find — это имена пяти каталогов (включая . ):

Обратите внимание, что объекты find не перечислены в определенном порядке. Если мы изменим -type d на -type f , вместо этого мы получим список всех файлов:

Теперь попробуем сопоставить по имени:

Мы ожидали, что он найдет все текстовые файлы, но выводит только ./numbers.txt . Проблема в том, что оболочка расширяет подстановочные знаки, такие как * перед выполнением команд. Так как *.txt в текущем каталоге расширяется до ./numbers.txt , команда, которую мы на самом деле выполнили, была следующей:

find сделал то, что мы просили; мы просто попросили не то.

Чтобы получить то, что мы хотим, давайте сделаем то, что мы сделали с grep : заключим *.txt в кавычки, чтобы оболочка не расширила подстановочный знак *. Таким образом, find на самом деле получает шаблон *.txt , а не расширенное имя файла number.txt :

Список и поиск

ls и find можно заставить делать похожие вещи при наличии правильных параметров, но в обычных обстоятельствах ls перечисляет все, что может, а find ищет вещи с определенными свойствами и показывает их.

Как мы уже говорили ранее, сила командной строки заключается в объединении инструментов. Мы видели, как это сделать с трубами; давайте посмотрим на другую технику. Как мы только что видели, найдите . -name "*.txt" дает нам список всех текстовых файлов в текущем каталоге или ниже него. Как мы можем объединить это с wc -l для подсчета строк во всех этих файлах?

Самый простой способ — поместить команду find внутрь $() :

Когда оболочка выполняет эту команду, первое, что она делает, это запускает то, что находится внутри $() . Затем он заменяет выражение $() выводом этой команды. Поскольку выводом find являются три имени файла ./writing/LittleWomen.txt , ./writing/haiku.txt и ./numbers.txt , оболочка создает команду:

Это то, что мы хотели. Это расширение — именно то, что делает оболочка, когда расширяет подстановочные знаки, такие как * и ? , но позволяет нам использовать любую команду, которую мы хотим, в качестве нашего собственного «шаблона».

Очень распространено совместное использование find и grep. Первый находит файлы, соответствующие шаблону; второй ищет строки внутри тех файлов, которые соответствуют другому шаблону. Здесь, например, мы можем найти файлы txt, содержащие слово «поиск», ища строку «поиск» во всех файлах .txt в текущем каталоге:

Сопоставление и вычитание

  1. найти существ -имя "*.dat" | grep -v единорог
  2. найти существ -имя *.dat | grep -v единорог
  3. grep -v "unicorn" $(найти существ -name "*.dat"))
  4. Ничего из вышеперечисленного.

Решение

Вариант 1. правильный. Помещение выражения соответствия в кавычки не позволяет оболочке расширить его, поэтому оно передается команде find.

Вариант 2 также работает в этом случае, потому что оболочка пытается расширить *.dat, но нет *. .dat в текущем каталоге, поэтому выражение с подстановочным знаком передается для поиска . Впервые мы столкнулись с этим в эпизоде ​​3.

Вариант 3 неверен, поскольку он ищет в содержимом файлов строки, которые не соответствуют «единорогу», а не ищет имена файлов.

Двоичные файлы

Мы сосредоточились исключительно на поиске шаблонов в текстовых файлах. Что делать, если ваши данные хранятся в виде изображений, в базах данных или в каком-либо другом формате?

Несколько инструментов расширяют grep для обработки нескольких нетекстовых форматов. Но более универсальный подход заключается в преобразовании данных в текст или извлечении текстовых элементов из данных. С одной стороны, это упрощает выполнение простых вещей. С другой стороны, сложные вещи обычно невозможны. Например, достаточно просто написать программу, которая будет извлекать размеры X и Y из файлов изображений для использования с grep, но как бы вы написали что-то для поиска значений в электронной таблице, ячейки которой содержат формулы?

Последний вариант — признать, что оболочка и обработка текста имеют свои ограничения, и использовать другой язык программирования. Когда придет время сделать это, не будьте слишком строги к оболочке: многие современные языки программирования позаимствовали у нее множество идей, а подражание — тоже самая искренняя форма похвалы.

Оболочка Unix старше, чем большинство людей, которые ее используют. Он просуществовал так долго, потому что это одна из самых продуктивных сред программирования из когда-либо созданных — возможно, даже самая продуктивная. Его синтаксис может быть загадочным, но люди, освоившие его, могут интерактивно экспериментировать с различными командами, а затем использовать полученные знания для автоматизации своей работы. Поначалу графические пользовательские интерфейсы могут быть проще в использовании, но после освоения производительность в оболочке становится непревзойденной. И, как писал Альфред Норт Уайтхед в 1911 году, «цивилизация развивается за счет увеличения числа важных операций, которые мы можем выполнять, не задумываясь о них».

Читайте также: